跳转至

窗口

PrismQML 通过 App.create_window(WindowType) 创建带导航的主窗口。

窗口类型

类型 枚举值 说明
WindowType.BAR 1 紧凑侧边导航(默认)
WindowType.SPLIT 0 展开式侧边导航
WindowType.FILLED 2 填充式分割窗口
from pathlib import Path

from prismqml import App, WindowType

app = App(application_icon=Path(__file__).with_name("app_icon.png"))

window = app.create_window(WindowType.BAR)     # 紧凑侧边导航
# window = app.create_window(WindowType.SPLIT) # 展开式侧边导航
# window = app.create_window(WindowType.FILLED)# 填充式分割

应用图标在 App 层配置一次即可;现有窗口、后续窗口、任务栏和默认启动画面会自动 继承。只有需要单独覆盖某个窗口时,才调用该窗口的 setWindowIcon()

添加导航页面

window.addPage(HomePage, "Home", "首页")        # QML 组件, 图标名, 导航文本
window.addPage(SettingsPage, "Settings", "设置")
window.show()

需要保留页面路由、但不在导航栏呈现时,把 visible 设为 False。页面索引和编程式 navigateTo() 不会改变:

window.addPage(HiddenPage, "Page", "隐藏页面", position="bottom", visible=False)

窗口特性

  • 懒加载 — 页面内容延迟到首次切换时加载,加快启动
  • 云母效果(Mica) — Windows 11 半透明背景(非 Fluent 皮肤下自动关闭,以保持各自表面范式)
  • 系统托盘 — 见 系统托盘
  • 启动画面SplashScreen 首屏就绪后自动淡出(默认挂载)

Mica 与 Acrylic

Mica(云母)

Fluent.Windows 在同时满足以下条件时自动应用 Windows 11 云母背板,无需手动调用 DWM API:

  • 配置项 Window.MicaEnabled 已开启(默认关闭)
  • Windows 11 且 Build ≥ 22621(DWMWA_SYSTEMBACKDROP_TYPE 最低支持版本)
  • 当前皮肤允许 Mica(见页面底部提示)
from prismqml.python.config import getConfigManager

getConfigManager().setMicaEnabled(True)   # 创建窗口前设置

需要对接任意 QWindow 时可直接使用 MicaManager

成员 说明
isMicaSupported 是否支持 DWM 云母背板
setMicaEffect(window, enabled, dark=False) 应用 / 关闭云母,成功返回 True
updateDarkMode(dark) 更新当前窗口的深色模式
setWindowCorner(window, rounded) 调整圆角偏好,不改变 Mica 状态
from prismqml import get_mica_manager

mica = get_mica_manager()
if not mica.setMicaEffect(window, True, dark=True):
    pass  # 当前平台不支持,窗口保持普通不透明背景

非 Windows、非 Win11 或 Build 过低时 isMicaSupportedFalsesetMicaEffect() 直接返回 False,无需平台分支处理。

Acrylic(亚克力)

Acrylic 不依赖系统背板:AcrylicHelper 截取窗口相对坐标的屏幕区域,模糊后通过 image://acrylic 提供给 QML Image

from prismqml import get_acrylic_helper

helper = get_acrylic_helper()
helper.blurRadius = 60                             # 取值 1–100,默认 100
url = helper.grabAndBlur(window, 0, 0, 300, 200)   # → "image://acrylic/<id>"
  • imageReady(str) 信号携带最新图片 URL;grabWindowFrame(window, x, y, width, height) 可原样截取可见窗口像素(不模糊)
  • App / register_types() 已自动注册 image://acrylic 图片提供器

标题栏通用动作

窗口可以在最小化、最大化、关闭按钮左侧放置一个可选的通用动作按钮。引擎只负责 标题栏位置、主题样式、命中区域和信号,动作含义由宿主决定(例如 AI、帮助或反馈):

window.set_caption_action("Bot", "AI")
window.on_caption_action_triggered(open_ai_assistant)
window.setCaptionAction(QStringLiteral("Bot"), QStringLiteral("AI"));
window.onCaptionActionTriggered(openAiAssistant);

也可以直接在 QML 窗口上配置:

Fluent.Windows {
    captionActionVisible: true
    captionActionIcon: "Bot"
    captionActionToolTip: "AI"
    onCaptionActionTriggered: openAiAssistant()
}

不需要动作时保持默认的 captionActionVisible: false 即可,不会为系统按钮额外预留空白。

启动画面

启动画面由 NavigationWindowCore 统一创建、覆盖窗口并等待首页就绪;窗口可见后 默认至少稳定展示 600ms,再播放退场动画。Python、C++ 和纯 QML 使用同一套生命周期。 宿主只传配置,不需要自行创建组件:

window.showSplash(title="PrismQML", subtitle="正在加载组件...")
# window.setSplashEnabled(False)  # 按需关闭
window.setSplash(true, {}, {}, QStringLiteral("正在加载组件..."));
import PrismQML as Fluent

Fluent.Windows {
    windowTitle: "My App"
    windowIcon: "qrc:/app_icon.svg"
    splashSubtitle: "正在加载..."
    // 可按产品需要覆盖;默认值来自 Enums.duration.splashMinimumVisible。
    splashMinimumVisibleDuration: 600
}

主窗口关闭时也复用同一套 PageTransition。默认使用 Enums.lazyAnimation.lazy_circle 收紧窗口内容;关闭确认完成后先播放收紧,动画完成 才提交真实关闭。关闭请求被宿主否决时,过渡会调用 stop() 恢复原页面。

Fluent.Windows {
    closeAnimationType: Enums.lazyAnimation.lazy_circle
    closeAnimation: null
}

closeAnimationType: Enums.lazyAnimation.none 会跳过视觉过渡并同步进入真实关闭;设置 Enums.lazyAnimation.custom 时,closeAnimation 使用前文相同的 Component 合同。 因此启动画面、懒加载页面和主窗口退场可以共享同一套内置或自定义生命周期。

收紧节奏由主窗口退场与页面切换共用:时长取 Enums.lazyLoadingTransitionMetrics.coverDuration(420ms),缓动取 Easing.InOutQuad。收紧的 progress 由 1 走到 0、半径随之线性缩放,所以 ease-in 类 曲线会让半径在大部分时长里几乎不动,最后几帧才跨完剩余全部距离;在低刷新率屏幕上, 观感就是窗口在收到一半时被直接切掉。真机实测两处节奏完全相同,因此共用一套值。

PageTransition 公开 coverDurationcoverEasing,自定义过渡可单点覆盖:

Fluent.PageTransition {
    coverDuration: 360
    coverEasing: Easing.InOutCubic
}

调整 coverDuration 时注意:懒加载页面切换的 Loader 激活预算由它推导(coverDurationloaderActivationHeadroom),因此改收紧时长不会挤掉加载指示器的可见时间。

启动画面退场动画

默认 SplashScreen 使用 Enums.lazyAnimation.lazy_circle:它与懒加载页面的收紧/展开过渡共用同一套生命周期。窗口级属性会转发到默认启动画面:

Fluent.Windows {
    splashExitAnimationType: Enums.lazyAnimation.none
    // 或:Enums.lazyAnimation.lazy_circle(默认)
    // splashExitAnimation: mySplashTransition
}

SplashScreen 也可以直接配置同名属性:

SplashScreen {
    exitAnimationType: Enums.lazyAnimation.lazy_circle
    exitAnimation: null
}

启动画面退场模式通过 Enums.lazyAnimation 访问;普通 StackedWidget 切页模式才使用 Enums.animation

行为
Enums.lazyAnimation.none 不创建过渡后端,finish() 同步完成并隐藏启动画面。
Enums.lazyAnimation.lazy_circle 默认圆形收紧/展开过渡;保留首帧、目标页换帧和失败回退语义。
Enums.lazyAnimation.custom 使用 exitAnimation / splashExitAnimation 提供的 Component

自定义 Component 必须实现以下合同。方法的 sourceItem 参数是当前要收紧或展开的源项;状态和信号由 PageTransition 读取与转发。

Component {
    Item {
        property bool active: false
        property bool running: false
        property bool collapsing: false
        property bool collapsed: false
        property real progress: 0

        signal collapseStarted()
        signal collapseFinished()
        signal expandStarted()
        signal expandFinished()

        function collapse(sourceItem) { /* ... */ return true }
        function expand(sourceItem) { /* ... */ return true }
        function stop() { /* cancel and restore your state */ }
    }
}

collapse() / expand() 应在开始和完成时分别发出对应信号,并在 progresscollapsingcollapsed 等状态上保持一致;stop() 用于取消当前操作。调用 finish() 时,默认启动画面会调用 expand(sourceItem),完成信号到达后才隐藏并发出 finished()。懒加载页面通常先调用 collapse(sourceItem),切换内容后再调用 expand(sourceItem)

Component 缺少合同成员、创建失败或内置过渡无法捕获源项时,门面会记录错误并按无动画路径发出开始/完成信号,保证源项处于确定的最终可见性;自定义实现应让 stop() 可重复调用。动画完成后门面会释放源项引用,避免下一次 stop() 重新显示已经完成收紧的旧页面。

纯 QML 窗口还可以通过 splashComponent 替换视觉组件;自定义根对象必须提供 finish() 方法,框架会在首页就绪时调用它。

纯 QML 的 Fluent.Windows 会在对象创建完成时自动注册到 App 的启动页生命周期, 无需宿主手动调用内部绑定方法。非标准 QML 窗口可通过公开的 app.attach_startup_window(window) 接入同一套 FastSplash 生命周期。

PageTransition

需要在页面或其他覆盖层复用同一套过渡时,可直接使用公开的 PageTransition

PageTransition {
    id: transition
    animationType: Enums.lazyAnimation.lazy_circle
    revealTarget: true

    function showPage(page) {
        transition.expand(page)
    }
}

它公开 collapse(sourceItem)expand(sourceItem)stop() 方法,以及 activerunningcollapsingcollapsedprogress 状态和四个生命周期信号。customAnimation 属性接受上面的 Component 合同;自定义模式推荐同时设置 animationType: Enums.lazyAnimation.customanimationType: Enums.lazyAnimation.none 会绕过动态加载并同步发出开始/完成信号。

懒加载页面默认使用 Enums.lazyAnimation.lazy_circle,它与普通 StackedWidget 切页动画相互独立。

非 Fluent 皮肤下的窗口

新粗野、复古票据与新拟态都会自动关闭 Mica,并切换到各自的表面、边框、 阴影与导航状态。这些都由皮肤系统处理,无需手动配置。