Add Qt guidance and HTML prototype workflow

This commit is contained in:
QiuSW
2026-07-18 18:01:40 +08:00
parent 2ed513bc25
commit 1ac5f3e8ee
4 changed files with 435 additions and 15 deletions
+132
View File
@@ -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 状态管理。
+262
View File
@@ -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)