Add Qt guidance and HTML prototype workflow
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: win-ui-ux-design
|
||||
description: 为 WinUI 3、Windows App SDK、XAML、Fluent Design,以及使用 PySide 或 PyQt 面向 Windows 的 Qt for Python 应用设计、评审和实现专业的 Windows 桌面端 UI/UX。当任务涉及 Windows 桌面应用外壳或界面、PySide6、PyQt6、PySide2、PyQt5、Qt Widgets、QML、导航与窗口化、标题栏、NavigationView 或框架等价控件选择、响应式 XAML 或 Qt 布局、主题资源、QPalette 或 QSS、Mica 或 Acrylic、键盘/鼠标/触控交互、无障碍、设计系统规范、UI 审查,或将设计转换为 WinUI 3、PySide 或 PyQt 代码时使用。
|
||||
description: 为 WinUI 3、Windows App SDK、XAML、Fluent Design,以及使用 PySide 或 PyQt 面向 Windows 的 Qt for Python 应用设计、评审和实现专业的 Windows 桌面端 UI/UX。当任务涉及 Windows 桌面应用外壳或界面、PySide6、PyQt6、PySide2、PyQt5、Qt Widgets、QML、导航与窗口化、标题栏、NavigationView 或框架等价控件选择、响应式 XAML 或 Qt 布局、主题资源、QPalette 或 QSS、Mica 或 Acrylic、HTML 交互原型、客户评审与设计确认、键盘/鼠标/触控交互、无障碍、设计系统规范、UI 审查,或将已确认的设计转换为 WinUI 3、PySide 或 PyQt 代码时使用。
|
||||
---
|
||||
|
||||
# Windows 桌面端 UI/UX 设计
|
||||
@@ -10,13 +10,15 @@ description: 为 WinUI 3、Windows App SDK、XAML、Fluent Design,以及使用
|
||||
## 遵循核心规则
|
||||
|
||||
- 先优化用户任务流程,再设计单个控件的样式。
|
||||
- 优先使用 WinUI 控件、系统资源和内置交互行为,再考虑创建自定义 UI。
|
||||
- 优先使用所选框架的标准控件、系统资源和内置交互行为,再考虑创建自定义 UI。
|
||||
- 将键盘、指针、触控、屏幕阅读器、缩放、主题和高对比度视为同一体验,而不是后期适配项。
|
||||
- 定义每个有意义的状态:默认、悬停、按下、焦点、选中、禁用、加载、空、错误、离线或不可用、成功,以及适用时的撤销。
|
||||
- 使用语义化 Token 和主题资源。不得只用颜色表达含义,也不得假设浅色模式的配色可直接用于深色模式。
|
||||
- 保持适合桌面工作的界面密度。不要放大移动端模式,也不要把常用命令隐藏在仅触控手势中。
|
||||
- 根据项目的 Windows App SDK 版本、目标操作系统、打包模型和依赖项,对每个 API、控件和 Toolkit 建议设置版本门槛。
|
||||
- 根据项目的框架与绑定版本、目标操作系统、打包模型和依赖项,对每个 API、控件和 Toolkit 建议设置版本门槛。
|
||||
- 区分 WinUI 3(`Microsoft.UI.Xaml`)与 UWP/WinUI 2(`Windows.UI.Xaml`)。未经验证不得跨框架复制 API。
|
||||
- 区分 PySide 与 PyQt,以及 Qt Widgets 与 QML。不要在同一应用中混用绑定,也不要把 WinUI 控件名直接写入 Qt 实现。
|
||||
- 将 HTML 原型视为可交互的设计规格和客户确认媒介,不视为最终桌面实现或原生行为证明。
|
||||
|
||||
## 执行工作流
|
||||
|
||||
@@ -30,30 +32,48 @@ description: 为 WinUI 3、Windows App SDK、XAML、Fluent Design,以及使用
|
||||
- 预期窗口尺寸、多窗口行为,以及调整大小和贴靠场景;
|
||||
- 主要输入方式,以及是否需要针对触控优化;
|
||||
- 品牌约束、浅色/深色行为和现有设计 Token。
|
||||
- 客户确认范围、原型保真度、交付方式、审批人和变更流程。
|
||||
|
||||
如果信息缺失,明确说明保守假设,并让版本敏感的建议保持条件化。
|
||||
|
||||
### 2. 建模体验
|
||||
### 2. 选择框架路线
|
||||
|
||||
先根据实际依赖选择且只选择一条实现路线:
|
||||
|
||||
- **WinUI 3:** 使用 `Microsoft.UI.Xaml`,并读取 [controls-and-patterns.md](references/controls-and-patterns.md) 与 [engineering-validation.md](references/engineering-validation.md)。
|
||||
- **PySide/PyQt:** 确认 PySide6、PyQt6 或遗留 Qt 5 绑定,再确定 Qt Widgets 或 QML;读取 [qt-pyside-pyqt.md](references/qt-pyside-pyqt.md),不要生成 XAML 或 WinUI API。
|
||||
|
||||
两条路线都必须读取 Windows 视觉基础与输入/无障碍基线。框架未知时先检查项目文件和导入语句,不要同时给出两套混杂实现。
|
||||
|
||||
### 3. 建模体验
|
||||
|
||||
定义主要用户任务、信息层级、窗口图、导航模型和命令界面。保持顶级导航浅而清晰。确定哪些工作应放在主窗口、辅助窗口、内联界面、浮出控件或模态对话框中。
|
||||
|
||||
先描述顺利路径和恢复路径,再制作原型或 XAML。在导航、调整大小、刷新和错误发生时保留用户上下文。
|
||||
先描述顺利路径和恢复路径,再制作原型或所选框架的界面代码。在导航、调整大小、刷新和错误发生时保留用户上下文。
|
||||
|
||||
### 3. 定义视觉系统
|
||||
### 4. 定义视觉系统
|
||||
|
||||
为字体、间距、几何、颜色、层级、材质、图标和动效建立精简的语义系统。除非品牌需要有意偏离,否则使用 Windows 默认规范。阅读 [windows-foundations.md](references/windows-foundations.md),了解当前 Fluent 原则、响应式断点、主题、材质和动效指南。
|
||||
|
||||
### 4. 将意图映射到控件和模式
|
||||
### 5. 将意图映射到控件和模式
|
||||
|
||||
根据交互语义选择控件,而不是根据外观或任意的项目数量阈值。跨菜单、工具栏、上下文菜单和快捷键复用命令。选择导航、集合、表单、设置、反馈或数据表格模式前,阅读 [controls-and-patterns.md](references/controls-and-patterns.md)。
|
||||
根据交互语义选择控件,而不是根据外观或任意的项目数量阈值。跨菜单、工具栏、上下文菜单和快捷键复用命令。WinUI 项目读取 [controls-and-patterns.md](references/controls-and-patterns.md);PySide/PyQt 项目读取 [qt-pyside-pyqt.md](references/qt-pyside-pyqt.md) 中的 Qt 控件映射。
|
||||
|
||||
### 5. 规定交互与无障碍
|
||||
### 6. 规定交互与无障碍
|
||||
|
||||
记录焦点顺序、方向键行为、访问键、快捷键、指针提示、上下文菜单、触控目标、拖拽替代方式、无障碍名称、状态播报、对比度和缩放。阅读 [input-accessibility.md](references/input-accessibility.md),了解必需的交互与无障碍基线。
|
||||
记录焦点顺序、方向键行为、访问键、快捷键、指针提示、上下文菜单、触控目标、拖拽替代方式、无障碍名称、状态播报、对比度和缩放。阅读 [input-accessibility.md](references/input-accessibility.md),了解必需的交互与无障碍基线。该参考中的 `AutomationProperties` 仅适用于 WinUI;PySide/PyQt 项目必须使用 [qt-pyside-pyqt.md](references/qt-pyside-pyqt.md) 中的 Qt Accessibility 映射。
|
||||
|
||||
### 6. 工程实现与验证
|
||||
### 7. 制作 HTML 原型并取得确认
|
||||
|
||||
请求实现时,遵循现有架构,并集中管理 Token、命令和状态。保留虚拟化,避免在 UI 线程上执行同步工作。阅读 [engineering-validation.md](references/engineering-validation.md),了解版本门槛、实现实践、性能检查和测试矩阵。
|
||||
对于新产品、主要页面或显著改版,在正式桌面实现前制作可本地运行的 HTML/CSS/JavaScript 交互原型。它必须复用已定义的 Token、内容、状态矩阵和窗口断点,覆盖主流程、关键异常和空/加载/禁用状态,而不接入生产后端。
|
||||
|
||||
向客户明确浏览器与 WinUI/Qt 在原生控件、窗口管理、字体渲染、系统材质、DPI、无障碍和性能上的差异。以书面验收清单确认信息架构、布局、视觉、文案、流程和状态;记录未确认项与不在原型验收范围内的原生能力。只有确认后才进入桌面实现。小型局部修改可说明理由后跳过此门禁。
|
||||
|
||||
制作或评审原型时读取 [html-prototype-handoff.md](references/html-prototype-handoff.md),并在交接时建立 HTML 组件到 WinUI 或 Qt 控件的映射。客户要求改变已确认设计时,先更新原型和验收记录,再修改桌面实现。
|
||||
|
||||
### 8. 工程实现与验证
|
||||
|
||||
请求实现时,遵循现有架构,并集中管理 Token、命令和状态。保留虚拟化,避免在 UI 线程上执行同步工作。WinUI 项目读取 [engineering-validation.md](references/engineering-validation.md);PySide/PyQt 项目读取 [qt-pyside-pyqt.md](references/qt-pyside-pyqt.md) 中的 Qt 工程、线程、主题、部署和测试规范。
|
||||
|
||||
在真实的紧凑、中等和宽窗口宽度下验证结果,而不是只在全屏显示器分辨率下验证。
|
||||
|
||||
@@ -69,6 +89,7 @@ description: 为 WinUI 3、Windows App SDK、XAML、Fluent Design,以及使用
|
||||
6. 交互与状态矩阵;
|
||||
7. 无障碍要求;
|
||||
8. 实现说明和验收检查。
|
||||
9. 需要客户确认时,提供可运行的 HTML 原型、确认清单和桌面控件映射。
|
||||
|
||||
对于评审,先按严重程度列出发现。每项发现都要指出受影响的界面或控件、用户影响、违反的 Windows 约定和具体修正方案。将正确性与无障碍缺陷同主观的视觉润色建议分开。
|
||||
|
||||
@@ -81,6 +102,11 @@ description: 为 WinUI 3、Windows App SDK、XAML、Fluent Design,以及使用
|
||||
- 不要假设当前 WinUI 3 项目中存在已归档的 Windows Community Toolkit `DataGrid`。
|
||||
- 不要把 Emoji 用作结构性界面图标;使用平台字形或一致的矢量图标集。
|
||||
- 不要强制在所有表面使用 Acrylic。用材质表达层级,并提供可读的纯色回退方案。
|
||||
- 当标准控件已经公开准确的无障碍名称时,不要强制设置 `AutomationProperties.Name`;仅在缺少语义时显式添加名称。
|
||||
- WinUI 标准控件已经公开准确的无障碍名称时,不要强制设置 `AutomationProperties.Name`;Qt 项目使用对应的 Qt Accessibility API,并且只在缺少语义时显式添加名称。
|
||||
- 不要默认确认每次删除。对频繁且可恢复的操作优先提供撤销;仅对代价高或不可逆的后果使用模态确认。
|
||||
- 不要把单一窗口尺寸、主题、DPI、区域设置或输入方式硬编码为设计基线。
|
||||
- 不要在一个进程中混用 PySide 与 PyQt,也不要混用绑定特有的 `Signal`/`Slot` 与 `pyqtSignal`/`pyqtSlot` API。
|
||||
- 不要从工作线程直接读取或修改 `QWidget`、Qt Quick 场景或其他 GUI 对象;通过队列信号把数据结果送回 GUI 线程。
|
||||
- 不要把 QSS 当作完整 CSS,也不要让全局样式表覆盖系统主题、高对比度、焦点和禁用状态。
|
||||
- 不要把 HTML 原型的 DOM、CSS 或 Web 组件逐字移植为 WinUI/Qt 控件,也不要承诺浏览器原型能证明原生窗口行为、性能或无障碍结果。
|
||||
- 不要为了原型接入生产数据库、真实凭据或不可逆操作;默认使用可重置的模拟数据和本地交互。
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
interface:
|
||||
display_name: "Windows UI/UX 设计"
|
||||
short_description: "设计、评审并实现专业的 Windows 桌面端体验"
|
||||
default_prompt: "使用 $win-ui-ux-design 设计并评审 Windows 桌面应用体验。"
|
||||
short_description: "设计、原型确认并实现 Windows 桌面端体验"
|
||||
default_prompt: "使用 $win-ui-ux-design 设计 Windows 桌面应用,先制作 HTML 交互原型供客户确认,再按项目实际采用 WinUI、PySide 或 PyQt 实现。"
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
# HTML 原型评审与桌面实现交接
|
||||
|
||||
## 目录
|
||||
|
||||
1. 适用范围与目标
|
||||
2. 原型前的设计冻结条件
|
||||
3. 原型技术与目录约束
|
||||
4. 必须覆盖的内容与状态
|
||||
5. 客户评审与验收边界
|
||||
6. 从 HTML 交接到 WinUI 或 Qt
|
||||
7. 变更管理与完成标准
|
||||
8. 常见反模式
|
||||
|
||||
## 1. 适用范围与目标
|
||||
|
||||
HTML 原型用于低成本验证信息架构、内容层级、视觉 Token、窗口断点、关键流程和状态反馈。它是设计规格的可交互表达,不是最终产品的 Web 版本。
|
||||
|
||||
以下情况默认制作原型:
|
||||
|
||||
- 新产品、主要窗口、关键业务流程或显著视觉改版;
|
||||
- 客户需要在原生开发前确认范围、流程或视觉;
|
||||
- 多角色、多状态或跨页面交互仅靠静态图难以说明;
|
||||
- WinUI、PySide/PyQt 团队需要统一实现基准。
|
||||
|
||||
仅修正文案、颜色、间距或单个明确控件时,可以说明理由后跳过。跳过不等于省略状态、无障碍和验收要求。
|
||||
|
||||
## 2. 原型前的设计冻结条件
|
||||
|
||||
开始写 HTML 前至少确定:
|
||||
|
||||
- 目标用户、核心任务和主流程;
|
||||
- 页面/窗口清单、导航模型和命令层级;
|
||||
- 目标桌面框架与控件映射方向;
|
||||
- 字体、颜色、间距、圆角、层级和动效 Token;
|
||||
- 紧凑、中等、宽窗口的布局策略;
|
||||
- 加载、空、错误、离线、禁用、成功、取消和撤销状态;
|
||||
- 原型要确认的决策、审批人和反馈截止方式。
|
||||
|
||||
仍有未知项时在原型内显式标注假设,不要用精致视觉掩盖未完成的产品决策。
|
||||
|
||||
## 3. 原型技术与目录约束
|
||||
|
||||
默认创建独立的 `prototype/` 目录,至少包含入口 HTML、样式、交互脚本和本地资源。项目已有前端原型栈时遵循现有结构;没有时优先使用简单、可直接打开或通过轻量本地服务器运行的 HTML/CSS/JavaScript。
|
||||
|
||||
- 默认不引入前端框架、构建链或组件库;只有复杂状态确有收益且团队能维护时才使用。
|
||||
- 不依赖外部 CDN、在线字体、远程图片或只有开发机可用的绝对路径。
|
||||
- 使用语义化 HTML、CSS 自定义属性和少量模块化 JavaScript,保持客户环境可重复运行。
|
||||
- 将设计 Token 集中定义,避免在各页面复制颜色、间距和字号。
|
||||
- 使用本地模拟数据或可重置 fixture;需要模拟接口时明确 schema、延迟、空数据和失败响应。
|
||||
- 不包含生产凭据、真实个人数据、生产数据库连接、遥测或不可逆操作。
|
||||
- 提供清晰的启动入口;不得要求客户先理解桌面工程的构建环境。
|
||||
|
||||
原型不是生产 Web 应用,不要提前建设路由框架、认证、完整后端、SEO、服务端渲染或发布基础设施,除非这些本身就是待确认体验的一部分。
|
||||
|
||||
## 4. 必须覆盖的内容与状态
|
||||
|
||||
至少实现:
|
||||
|
||||
- 主导航、页面层级和主要任务的端到端可点击路径;
|
||||
- 关键命令、菜单、对话框、表单验证、选择和反馈;
|
||||
- 默认、悬停、按下、焦点、选中和禁用状态;
|
||||
- 加载、空、错误、成功、取消、超时和过期结果;
|
||||
- 紧凑、中等、宽窗口的重排、折叠和滚动行为;
|
||||
- 浅色、深色,以及适用时的高对比度近似方案;
|
||||
- 键盘焦点顺序、Enter/Escape、常用快捷键和不依赖悬停的操作入口;
|
||||
- 真实长度的中文、数字、日期、错误文案和高密度示例数据。
|
||||
|
||||
避免只有首页和理想数据的“演示动画”。客户需要看到业务完成条件、失败后的恢复方式以及删除等高风险操作的后果。
|
||||
|
||||
## 5. 客户评审与验收边界
|
||||
|
||||
评审前提供场景脚本,而不是只给一个 URL 或目录。按用户任务引导客户检查并记录:
|
||||
|
||||
1. 信息架构和功能范围;
|
||||
2. 页面布局、密度和窗口断点;
|
||||
3. 品牌、颜色、字体、图标和动效方向;
|
||||
4. 文案、术语、数据字段和默认值;
|
||||
5. 主流程、异常流程、权限和不可用状态;
|
||||
6. 哪些内容已确认、需修改、暂缓或超出范围。
|
||||
|
||||
必须声明以下内容不能仅靠 HTML 验收:
|
||||
|
||||
- 原生标题栏、系统菜单、Snap Layouts、多窗口和任务栏行为;
|
||||
- WinUI/Qt 控件的精确尺寸、字体栅格化和系统主题差异;
|
||||
- Mica/Acrylic、原生弹出层、输入法和多显示器 DPI 行为;
|
||||
- Narrator/UI Automation/Qt Accessibility 的最终语义;
|
||||
- 启动速度、内存、虚拟化、线程、打包、升级和生产数据性能。
|
||||
|
||||
验收记录至少包含原型版本或提交、日期、审批人、确认项、遗留项和明确排除项。未回复不能自动视为确认。
|
||||
|
||||
## 6. 从 HTML 交接到 WinUI 或 Qt
|
||||
|
||||
确认后冻结原型版本,并建立追踪表:
|
||||
|
||||
| 原型项 | 设计 Token/状态 | WinUI 实现 | Qt Widgets/QML 实现 | 差异与验证 |
|
||||
|---|---|---|---|---|
|
||||
| 导航 | 层级、选中、折叠 | `NavigationView` 等 | `QListView` + 页面容器等 | 键盘、窗口断点 |
|
||||
| 共享命令 | 文本、图标、启用状态 | `XamlUICommand`/命令 | `QAction` | 快捷键、上下文 |
|
||||
| 数据集合 | 空、加载、选择、分页 | 虚拟化集合控件 | Model/View | 大数据性能 |
|
||||
| 对话与反馈 | 模态性、默认操作 | `ContentDialog`/信息条 | `QDialog`/语义 Banner | 焦点、Escape |
|
||||
|
||||
交接时遵循以下规则:
|
||||
|
||||
- 复用设计 Token 和状态名称,不复用 DOM 结构或逐字翻译 CSS。
|
||||
- 把模拟数据 schema 转成明确的领域模型、接口契约和错误类型。
|
||||
- 将 JavaScript 交互意图映射到桌面命令、信号/事件和状态管理。
|
||||
- 选择目标框架的标准控件;原型视觉与原生行为冲突时优先保证任务、可用性和平台约定。
|
||||
- 对无法一比一实现的材质、布局或动效给出差异说明,并在桌面端验收中重新确认。
|
||||
- 桌面实现完成后执行视觉对照,也必须单独完成原生键盘、无障碍、DPI、性能和打包测试。
|
||||
|
||||
## 7. 变更管理与完成标准
|
||||
|
||||
客户确认后的需求变化先回到原型和验收记录。评估它对页面、状态、数据契约、桌面控件、开发量和测试范围的影响,再更新原生实现。
|
||||
|
||||
HTML 原型阶段完成必须同时满足:
|
||||
|
||||
- 评审范围内流程和关键状态可操作;
|
||||
- 指定窗口宽度、主题和键盘路径已检查;
|
||||
- 不含真实凭据和生产副作用;
|
||||
- 客户能按说明独立运行;
|
||||
- 已形成书面确认、遗留项和排除项;
|
||||
- 已建立到 WinUI 或 Qt 的控件与状态映射。
|
||||
|
||||
## 8. 常见反模式
|
||||
|
||||
- 先写完整 HTML,再补用户流程、状态和验收目标。
|
||||
- 为一次性原型引入复杂前端框架、后端和部署平台。
|
||||
- 只实现理想路径,使用 `alert()` 代替真实错误、确认和恢复体验。
|
||||
- 用浏览器窗口模拟原生标题栏后承诺 Snap、系统菜单或窗口拖拽效果。
|
||||
- 把浏览器像素截图作为所有 DPI、主题和字体环境的最终标准。
|
||||
- 客户口头说“差不多”便开始开发,没有版本化确认和遗留项。
|
||||
- 桌面端直接复制 HTML 的控件结构、CSS 数值或 JavaScript 状态管理。
|
||||
@@ -0,0 +1,262 @@
|
||||
# Windows 上的 PySide/PyQt 工程指南
|
||||
|
||||
## 目录
|
||||
|
||||
1. 确认绑定与 UI 技术
|
||||
2. 将 Windows 交互意图映射到 Qt
|
||||
3. 架构、对象生命周期与数据模型
|
||||
4. 布局、窗口化与高 DPI
|
||||
5. 主题、QSS、图标与 Windows 材质
|
||||
6. 命令、键盘与无障碍
|
||||
7. 线程、异步与响应速度
|
||||
8. Designer、资源、设置与本地化
|
||||
9. 部署与测试
|
||||
10. 常见反模式
|
||||
11. 交付检查清单
|
||||
12. 官方资料
|
||||
|
||||
## 1. 确认绑定与 UI 技术
|
||||
|
||||
先检查 `pyproject.toml`、锁文件、requirements、导入语句和实际安装版本,再生成代码。
|
||||
|
||||
### 选择绑定
|
||||
|
||||
- 新项目优先选择 Qt 6 绑定,除非插件、操作系统或现有代码明确要求 Qt 5。
|
||||
- PySide6 是 Qt 官方 Python 绑定,采用 LGPLv3/GPLv3/商业许可组合;发布前确认应用对 Qt 许可义务的满足方式。
|
||||
- PyQt6 采用 GPLv3 或 Riverbank 商业许可,不提供 LGPL;闭源分发前必须确认许可方案。
|
||||
- 维护现有 PySide2/PyQt5 项目时遵循项目版本,不要在 UI 改造中顺带升级主版本。
|
||||
- 不要在一个进程或分发包中混用 PySide 与 PyQt。第三方组件的绑定必须与应用一致。
|
||||
|
||||
### 选择 UI 技术
|
||||
|
||||
| 场景 | 优先选择 |
|
||||
|---|---|
|
||||
| 高密度生产力工具、表格、菜单、工具栏、停靠面板 | Qt Widgets |
|
||||
| 既有 `.ui` 文件或大量成熟 QWidget 控件 | Qt Widgets |
|
||||
| 高度定制的视觉、连续动画、触控优先界面 | Qt Quick/QML |
|
||||
| Widgets 与 QML 混合 | 仅在价值明确时采用,并定义边界、线程、焦点和无障碍责任 |
|
||||
|
||||
不要把 Qt Quick 仅当作“更现代的 Widgets”,也不要为了原生外观强行用 Widgets 实现复杂动画。根据任务、团队能力、组件生态、性能、部署和无障碍要求选择。
|
||||
|
||||
### 保持绑定 API 一致
|
||||
|
||||
- PySide 使用 `Signal`、`Slot`、`Property`;PyQt 使用 `pyqtSignal`、`pyqtSlot`、`pyqtProperty`。
|
||||
- PySide 项目仅在项目已统一启用时使用 `snake_case` 或 `true_property` 特性;不要与默认 camelCase 风格随机混用。
|
||||
- 生成示例时沿用仓库现有导入风格、枚举写法和 UI 构建方式。
|
||||
|
||||
## 2. 将 Windows 交互意图映射到 Qt
|
||||
|
||||
根据语义选择控件,不要逐字翻译 WinUI 控件名:
|
||||
|
||||
| Windows/WinUI 意图 | Qt Widgets 实现 | 说明 |
|
||||
|---|---|---|
|
||||
| 应用主窗口 | `QMainWindow` + `centralWidget` | 可组合菜单栏、工具栏、状态栏和停靠面板 |
|
||||
| 顶级导航 | 带 Model 的 `QListView` + `QStackedWidget` | 小型静态同级页也可用 `QTabWidget`;导航必须有文本标签 |
|
||||
| 文档标签页 | `QTabWidget` 或 `QTabBar` + 内容容器 | 定义关闭、重排、未保存和快捷键行为 |
|
||||
| 辅助工作面板 | `QDockWidget` | 定义允许区域、浮动、关闭和状态恢复 |
|
||||
| 分栏工作区 | `QSplitter` | 设置合理最小尺寸与折叠行为 |
|
||||
| 页面级命令 | `QAction` + `QToolBar`/按钮 | 同一 `QAction` 复用于菜单、工具栏和快捷键 |
|
||||
| 应用菜单 | `QMenuBar`、`QMenu`、`QAction` | 使用标准菜单分组和角色 |
|
||||
| 上下文命令 | `QMenu` 或 `QAction` 集合 | 同时提供可见或键盘访问路径 |
|
||||
| 列表 | `QListView` + `QAbstractListModel` | 动态或大型数据不要依赖 `QListWidget` |
|
||||
| 表格 | `QTableView` + `QAbstractTableModel` | 排序/筛选使用 `QSortFilterProxyModel` |
|
||||
| 树 | `QTreeView` + `QAbstractItemModel` | 保持展开、选择和键盘行为 |
|
||||
| 简单表单 | `QFormLayout` + 标准输入控件 | 设置标签 Buddy、验证和错误位置 |
|
||||
| 模态任务 | `QDialog` + `QDialogButtonBox` | 仅用于真正需要阻塞的决策或短任务 |
|
||||
| 简单系统消息 | `QMessageBox` | 不要用于频繁状态或长文本工作流 |
|
||||
| 内联信息条 | 自定义语义化 Banner `QWidget` | 包含图标、文本、操作和关闭入口,不要用状态栏替代关键错误 |
|
||||
| 确定进度 | `QProgressBar` | 提供取消、失败和完成状态 |
|
||||
| 阻塞进度 | `QProgressDialog` | 仅在确实需要窗口级阻塞时使用 |
|
||||
| 持久设置 | `QSettings` | 先设置组织名和应用名,定义迁移与默认值 |
|
||||
|
||||
Qt Quick/QML 项目使用 Qt Quick Controls 的等价语义控件,并为 Python 暴露的状态使用 `Signal`、`Slot` 和带通知信号的 `Property`。不要把 QWidget 嵌入 QML 作为常规布局方案。
|
||||
|
||||
## 3. 架构、对象生命周期与数据模型
|
||||
|
||||
### 对象与职责
|
||||
|
||||
- 让 View 负责渲染和输入转发,让领域/应用服务负责业务规则、I/O 和持久化。
|
||||
- 使用 `QObject` 的父子所有权管理 Qt 对象生命周期;不要同时建立不必要的 Python 强引用环。
|
||||
- 对需要延迟销毁的 `QObject` 使用 `deleteLater()`,尤其是跨事件循环或线程退出时。
|
||||
- 将共享用户操作建模为 `QAction`,避免在多个按钮和菜单处理器中复制逻辑。
|
||||
- 在关闭窗口前处理未保存更改,但不要把业务保存逻辑塞入 `closeEvent()`。
|
||||
|
||||
### 信号与槽
|
||||
|
||||
- PySide 类中将作为连接目标的方法标记为 `@Slot(...)`;官方建议这样做以减少运行时开销,并正确表达线程亲和性。
|
||||
- 让信号载荷传递不可变数据、标识符或轻量结果,不要跨线程传递需要在工作线程访问的 GUI 对象。
|
||||
- 明确连接的所有者和断开时机,避免重复连接导致一次操作执行多次。
|
||||
- QML 可见属性必须提供通知信号,否则绑定不会可靠更新。
|
||||
|
||||
### Model/View
|
||||
|
||||
- 动态、共享、可排序筛选或可能变大的数据使用 `QListView`、`QTableView`、`QTreeView` 与 `QAbstractItemModel` 派生模型。
|
||||
- 一维和二维数据分别优先从 `QAbstractListModel`、`QAbstractTableModel` 开始,不要无必要直接实现完整 `QAbstractItemModel`。
|
||||
- 使用 `QSortFilterProxyModel` 处理排序和筛选,不要为每次查询复制整个源数据集合。
|
||||
- 插入、删除、移动和重置模型时使用正确的 begin/end 通知;不得只修改 Python 列表后强制刷新视图。
|
||||
- 自定义绘制和编辑使用 `QStyledItemDelegate`;不要为每个单元格创建常驻 QWidget。
|
||||
- `QListWidget`、`QTableWidget`、`QTreeWidget` 仅适合小型、简单、不会共享模型的数据。
|
||||
|
||||
## 4. 布局、窗口化与高 DPI
|
||||
|
||||
### 布局
|
||||
|
||||
- 使用 `QLayout` 派生布局、`QSizePolicy`、stretch、`sizeHint()` 和最小尺寸,不要用 `setGeometry()` 手工排列常规界面。
|
||||
- 需要随宽度换行的自定义控件实现合理的 `heightForWidth()`;内容变化时调用 `updateGeometry()`。
|
||||
- 为窗口定义可用的最小尺寸,而不是固定尺寸。长文本、翻译和字体放大后仍应可操作。
|
||||
- 在少量语义断点下重排或显示/隐藏次要面板;不要在每次 `resizeEvent()` 中重建整棵 Widget 树。
|
||||
- 响应式切换时保留焦点、选择、滚动、编辑和展开状态。
|
||||
|
||||
### 主窗口与窗口状态
|
||||
|
||||
- `QMainWindow` 只把一个控件设置为 `centralWidget`,再通过 Qt 提供的 API 管理菜单栏、工具栏、状态栏和 `QDockWidget`。
|
||||
- 使用 `saveGeometry()`/`restoreGeometry()` 和 `QMainWindow.saveState()`/`restoreState()` 持久化窗口与停靠布局。
|
||||
- 恢复窗口时检查当前屏幕可用区域,防止窗口因显示器移除或 DPI 变化而出现在屏幕外。
|
||||
- 为辅助窗口定义所有者、模态性、任务栏显示、激活、关闭和共享数据生命周期。
|
||||
- 优先保留原生窗口框架。无边框窗口需要自行正确实现缩放命中测试、拖动、系统菜单、标题按钮、Snap Layouts、高 DPI 和无障碍,除非产品价值足以承担成本,否则不要使用。
|
||||
|
||||
### 高 DPI 与多显示器
|
||||
|
||||
- Qt 6 以设备无关像素描述大多数 Widget、Quick、事件和窗口几何;不要再次手工乘系统缩放比例。
|
||||
- 自定义像素绘制或图像几何时读取 `devicePixelRatio()`;不要把物理像素当作布局单位。
|
||||
- 使用 SVG、`QIcon` 多尺寸资源或 `@2x` 高分辨率资源。验证 100%、125%、150%、200% 以及跨显示器移动。
|
||||
- 屏幕几何使用 `QScreen` 的设备无关坐标;不要假设多个屏幕组成无间隙的物理像素网格。
|
||||
|
||||
## 5. 主题、QSS、图标与 Windows 材质
|
||||
|
||||
### 主题优先级
|
||||
|
||||
1. 优先让 `QStyle` 和系统 `QPalette` 提供平台行为与控件状态。
|
||||
2. 用语义 Token 生成有限的自定义 `QPalette` 或组件级 QSS。
|
||||
3. 只有品牌需要时才替换标准控件绘制或实现自定义 `QStyle`。
|
||||
|
||||
`QPalette` 为活动、非活动和禁用状态提供颜色组。覆盖颜色时同时定义这些状态,并独立验证浅色、深色和高对比度。
|
||||
|
||||
Qt 6.5 或更高版本可通过 `QGuiApplication.styleHints().colorScheme()` 读取系统配色方案,并监听 `colorSchemeChanged`。处理主题变化时也要响应 `QEvent.PaletteChange` 或 `QEvent.ApplicationPaletteChange`。使用前检查项目 Qt 版本;较旧版本不得生成不存在的 API。
|
||||
|
||||
Qt 6.10 或更高版本提供更多平台无障碍提示;低版本仍必须通过实际 Windows 高对比度测试验证,而不是自行猜测系统颜色。
|
||||
|
||||
### QSS
|
||||
|
||||
- QSS 不是完整 CSS:不要期待 Web 布局、CSS 变量、继承和选择器行为完全一致。
|
||||
- 避免 `QWidget { ... }` 等大范围规则覆盖所有标准状态。
|
||||
- 为 hover、pressed、checked、selected、disabled、focus、active/inactive 和高对比度定义可辨识行为。
|
||||
- 使用动态属性选择器时,属性变化后按项目需要重新 polish;不要依赖偶然刷新。
|
||||
- 样式表可能改变原生绘制和尺寸提示。修改后重新测试菜单、滚动条、输入法、焦点框、停靠窗口和高 DPI。
|
||||
|
||||
### 图标与 Windows 材质
|
||||
|
||||
- 使用一致的 SVG/`QIcon` 资源,为 normal、disabled、active、selected 等模式提供可读变体。
|
||||
- 不要用 Emoji 作为结构图标,也不要依赖某台开发机才存在的字体图标。
|
||||
- Qt Widgets/PySide 没有与 WinUI `MicaBackdrop` 完全等价的跨版本 API。需要 Mica/Acrylic 时,把 Windows 原生集成隔离为可选适配层,按 Windows/Qt 版本检查,并始终提供纯色 `QPalette` 回退。
|
||||
- 不要为装饰效果移除原生标题栏、破坏高对比度或引入不可维护的全局事件过滤器。
|
||||
|
||||
## 6. 命令、键盘与无障碍
|
||||
|
||||
### 命令与键盘
|
||||
|
||||
- 用 `QAction` 集中管理文本、图标、启用/选中状态和快捷键,并复用于菜单、工具栏、按钮或上下文菜单。
|
||||
- 标准操作优先使用 `QKeySequence.StandardKey`,避免硬编码与平台约定冲突的组合键。
|
||||
- 使用 `QShortcut` 时设置合适的 `Qt.ShortcutContext`;不要让页面快捷键意外覆盖整个应用。
|
||||
- 使用标签中的 `&` 和 `QLabel.setBuddy()` 提供访问键。处理中文界面时仍要检查访问键是否重复和是否可发现。
|
||||
- 优先使用自然 Tab 顺序,仅在布局顺序无法表达正确流程时使用 `QWidget.setTabOrder()`。
|
||||
- 所有悬停、右键和拖拽加速操作都必须有可见或键盘等价路径。
|
||||
|
||||
### 无障碍
|
||||
|
||||
- 标准 Widgets 与 Qt Quick Controls 已提供基础无障碍接口,优先复用它们。
|
||||
- 仅在可见文本无法形成正确名称时设置 `accessibleName`;把补充说明放入 `accessibleDescription`。
|
||||
- 为表单建立标签 Buddy 和合理焦点顺序;不要只通过占位符标识输入字段。
|
||||
- 自定义 QWidget 需要公开正确角色、名称、状态、值、操作和事件;复杂控件根据需要实现 `QAccessibleInterface`/`QAccessibleWidget`。
|
||||
- QML 自定义项使用 `Accessible` 附加属性公开角色、名称、描述和操作。
|
||||
- 用 Narrator、Accessibility Insights/Inspect、键盘、高对比度和文本/显示缩放验证真实体验。
|
||||
|
||||
## 7. 线程、异步与响应速度
|
||||
|
||||
### GUI 线程规则
|
||||
|
||||
- `QWidget` 及其子类不是可重入对象,只能在 GUI 主线程创建和访问。Qt Quick 场景对象也不得从工作线程直接修改。
|
||||
- 后台工作使用 worker `QObject` + `moveToThread()`,或 `QThreadPool` + `QRunnable`;根据项目复杂度选择一种模式并统一。
|
||||
- 通过默认 AutoConnection 或显式 QueuedConnection 的信号把结果送回 GUI 线程。
|
||||
- 对具有事件循环的接收者使用绑定对应的 Slot 装饰器,确保代码在接收对象所属线程执行。
|
||||
- 在线程退出时使用 `quit()`、`wait()` 和 `deleteLater()` 建立明确的清理链;关闭窗口后不得让回调访问已销毁 UI。
|
||||
- 不要对同一线程使用 BlockingQueuedConnection,这会导致死锁。
|
||||
|
||||
### 任务设计
|
||||
|
||||
- 长任务提供进度、取消和最终状态;取消必须检查任务是否仍可安全提交结果。
|
||||
- 搜索、预览和重新加载使用请求 ID 或取消令牌忽略过期结果。
|
||||
- 网络请求优先使用事件驱动的 `QNetworkAccessManager`,或在工作线程使用不会触碰 GUI 的客户端。
|
||||
- 不要在槽函数中执行阻塞 I/O,也不要用频繁 `processEvents()` 掩盖冻结。
|
||||
- 需要 `asyncio` 时沿用项目已有事件循环集成。采用 `PySide6.QtAsyncio` 前核对精确版本和支持范围,不要同时运行两个互相竞争的主事件循环。
|
||||
|
||||
## 8. Designer、资源、设置与本地化
|
||||
|
||||
- Qt Widgets Designer 生成的 `.ui` 文件应通过 `pyside6-uic`/`pyuic6` 生成代码,或由项目统一使用 `QUiLoader` 运行时加载。
|
||||
- 不要手工编辑生成的 `ui_*.py`;在继承/组合的业务类中扩展界面,重新生成时避免丢失修改。
|
||||
- PySide 官方建议优先使用与绑定版本匹配的 `pyside6-uic`,避免直接调用不匹配的独立 `uic`。
|
||||
- 使用 `.qrc` 与 `pyside6-rcc`/对应 PyQt 工具管理图标和资源,或采用项目已经验证的包资源方案。
|
||||
- 使用 `QSettings` 前设置组织名、域和应用名;为设置键、默认值、版本迁移和损坏恢复建立规范。
|
||||
- 使用 `tr()`/翻译上下文和 `QTranslator` 进行本地化。不要拼接句子;测试复数、快捷键、长文本和从右到左布局。
|
||||
|
||||
## 9. 部署与测试
|
||||
|
||||
### 部署
|
||||
|
||||
- 固定 Python、绑定、Qt 和打包工具版本,并在干净虚拟环境中构建。
|
||||
- PySide6 优先评估官方 `pyside6-deploy`;它使用 `pysidedeploy.spec` 保存配置,并支持 `--dry-run` 查看实际命令。
|
||||
- PyQt 使用项目许可和工具链已验证的打包方案;不要把 PySide 部署命令用于 PyQt。
|
||||
- 检查 Qt 平台插件、图像格式插件、QML imports、翻译、OpenSSL/多媒体依赖、MSVC Runtime、应用图标和资源是否完整。
|
||||
- 在干净 Windows 虚拟机上测试首次启动、无开发环境运行、非 ASCII 路径、只读目录、多用户配置、升级与卸载。
|
||||
- 发布前确认代码签名、安装器、文件关联、协议处理、自动更新和许可文件要求。
|
||||
|
||||
### 测试
|
||||
|
||||
- 使用 Qt Test/QTest 或项目现有测试栈覆盖关键 Widget、快捷键、模型通知和信号行为。
|
||||
- 对 Model/View 测试插入、删除、移动、排序、筛选、编辑、空数据和超大数据。
|
||||
- 对线程测试取消、窗口提前关闭、过期结果、异常和应用退出。
|
||||
- 执行 Windows 测试矩阵:最低支持版本与当前 Windows 11;100%–200% 缩放;跨显示器;浅色、深色、高对比度;键盘、鼠标和声明支持的触控;Narrator。
|
||||
- 测试打包产物,而不只测试源码环境。
|
||||
|
||||
## 10. 常见反模式
|
||||
|
||||
- 在同一项目中混用 `PySide6` 与 `PyQt6` 导入。
|
||||
- 从工作线程调用 Widget 方法或把 Widget 传给 worker。
|
||||
- 用 `time.sleep()`、同步网络或大循环阻塞 GUI 线程。
|
||||
- 为动态表格使用 `QTableWidget` 并为每个单元格嵌入 Widget。
|
||||
- 在每次窗口调整大小时销毁并重建全部页面。
|
||||
- 用固定坐标、固定字体像素或手动 DPI 倍增代替 Qt 布局系统。
|
||||
- 用全局 QSS 抹掉原生焦点、禁用、选择、高对比度和非活动窗口状态。
|
||||
- 手工编辑 `pyside6-uic`/`pyuic6` 生成文件。
|
||||
- 无版本检查地复制 Qt C++、旧 PySide2、PyQt5 或另一个绑定的示例。
|
||||
- 为获得 Mica/Acrylic 无条件启用无边框窗口或私有 Windows API。
|
||||
|
||||
## 11. 交付检查清单
|
||||
|
||||
- [ ] 已确认绑定、精确版本、Qt Widgets/QML 路线和许可证。
|
||||
- [ ] 未混用 PySide/PyQt 或绑定特有 API。
|
||||
- [ ] 标准控件、Model/View、`QAction` 和布局系统得到优先使用。
|
||||
- [ ] GUI 对象只在主线程访问,后台结果通过队列信号返回。
|
||||
- [ ] 主题跟随系统,QSS 未破坏高对比度、焦点或禁用状态。
|
||||
- [ ] 窗口在调整大小、贴靠、跨显示器和 100%–200% 缩放时可用。
|
||||
- [ ] 键盘、上下文菜单、拖拽替代方式和无障碍语义完整。
|
||||
- [ ] 加载、空、错误、取消、超时、过期结果和撤销状态已处理。
|
||||
- [ ] Designer 生成代码、资源和设置具有可重复的生成/迁移流程。
|
||||
- [ ] 已在干净 Windows 环境测试最终打包产物。
|
||||
|
||||
## 12. 官方资料
|
||||
|
||||
- [Qt for Python / PySide6](https://doc.qt.io/qtforpython-6/)
|
||||
- [PyQt 与许可](https://riverbankcomputing.com/software/pyqt)
|
||||
- [PySide 信号与槽](https://doc.qt.io/qtforpython-6/tutorials/basictutorial/signals_and_slots.html)
|
||||
- [Qt 线程与 QObject](https://doc.qt.io/qt-6/threads-qobject.html)
|
||||
- [Qt Model/View 编程](https://doc.qt.io/qt-6/model-view-programming.html)
|
||||
- [Qt Widgets 布局管理](https://doc.qt.io/qt-6/layout.html)
|
||||
- [Qt 高 DPI](https://doc.qt.io/qt-6/highdpi.html)
|
||||
- [QStyleHints 与系统配色](https://doc.qt.io/qt-6/qstylehints.html)
|
||||
- [Qt 样式表参考](https://doc.qt.io/qt-6/stylesheet-reference.html)
|
||||
- [Qt 无障碍](https://doc.qt.io/qt-6/accessible.html)
|
||||
- [QWidget 应用无障碍](https://doc.qt.io/qt-6/accessible-qwidget.html)
|
||||
- [PySide6 部署](https://doc.qt.io/qtforpython-6/deployment/index.html)
|
||||
- [pyside6-deploy](https://doc.qt.io/qtforpython-6/deployment/deployment-pyside6-deploy.html)
|
||||
- [pyside6-uic](https://doc.qt.io/qtforpython-6/tools/pyside-uic.html)
|
||||
Reference in New Issue
Block a user