project_theme_system.md 2.01 KB
name: UI 主题系统架构
description: theme.py 是设计系统单一真相源,业务代码不写 inline setStyleSheet
type: project
originSessionId: 21abab40-0d6c-449a-ae72-9ca03205f077

2026-05-09 重构上线(分支 feat/ui-redesign-apple-theme):

架构

  • theme.py 包含 TOKENS_LIGHT / TOKENS_DARK(24 个语义颜色)/ SIZES(圆角/间距/字号)/ FONT_STACK
  • build_qss(mode) 拼出完整 QSS 字符串
  • ThemeManager(QObject) 监听 QGuiApplication.styleHints().colorSchemeChanged 自动切换
  • apply_theme(app)image_generator.py main() 创建 QApplication 后立即调用
  • get_color(token, fallback) 用于 QSS 命中不到的渲染层 API(如 setForeground

业务代码规则

  • :x: 不要写 widget.setStyleSheet(...) 装饰样式
  • :white_check_mark:setObjectName("xxx") 命中 #xxx 选择器
  • :white_check_mark:setProperty("variant", "primary"|"danger"|"ghost"|"link"|"success-flash") 命中 [variant="..."] 按钮变体
  • :white_check_mark:setProperty("status", "success"|"warning"|"danger"|"info"|"muted") + style().polish() 命中 status label
  • :white_check_mark:setProperty("role", "title"|"secondary"|"caption"|"muted"|"thumb"|"thumb_index") 命中通用 label 角色
  • :white_check_mark:setProperty("drag_state", "idle"|"active") 命中拖拽态
  • :white_check_mark:setProperty("has_image", "true"|"false") 命中预览图占位/已显示

仅允许的 inline setStyleSheet

  • 平台 hack(macOS 占位符颜色 etc.)— image_generator.py 1292/1356
  • 单点临时高亮反馈(< 3 秒自动恢复)

Why:之前 65 处零散 setStyleSheet 让深色模式无法实现,且改一个圆角要找十处。集中后一处改全局。

How to apply:未来加新 widget / 改外观时:

  1. 优先看 theme.py 里有没有合适的现成 token / variant / role
  2. 如果没有,加到 theme.py 里(保持单一真相源),别再开 inline setStyleSheet 的口子
  3. 状态切换(图标变化、颜色反馈)用 setProperty + style().polish(),不要 inline setStyleSheet