[DTK] 为AI 时代的DTK 造轮子, 为DTK引入设计跨端 云生成的能力,快来讨论吧
Tofloor
poster avatar
ad1998
deepin
7 hours ago
Author

DTK_CSS_架构图.png

DTK CSS 功能开发计划书

版本:v0.1(草案,待确认定稿) · 日期:2026-08-13 流程:先定稿本计划书 → 用户确认 → 按计划进入开发


0. 文档目的

本计划书研究 DTK(Deepin ToolKit)框架的样式体系,提出在其上新增 「DTK CSS」 能力的整体方案:让开发者用接近 Web CSS 的语法为 DTK 应用描述界面样式,由引擎把 CSS 翻译为 DTK 原生的 DPalette / DStyle / DFontSizeManager 以及安全的 QSS 桥接,从而兼顾明暗主题、控件状态与 DTK 视觉规范。


1. 背景与目标

1.1 现状

  • DTK 应用当前做界面样式主要靠 C++ 调用 DPalette / DStyle / DFontSizeManager,或 DTK 5.x 的** QSS .theme 文件**(DThemeManager)。
  • 从 DTK 6.0 起 DThemeManager 已废弃,主题管理并入 dtkguiDGuiApplicationHelper,改为以调色板(palette)为主线。
  • 对熟悉 Web/CSS 的开发者而言,现有方式不够直观,缺少一份「声明式、可复用、可主题化」的样式表。

1.2 目标

  • 提供一套 DTK CSS 语言 + 解析/应用引擎:用 CSS 选择器 + 属性描述样式。

  • 引擎把 CSS 翻译为 DTK 原生样式 API,做到:

    • 主题感知:明暗双调色板,跟随系统/应用主题切换,无需重启;
    • 状态完整normal / hover / pressed / disabled / focus
    • 渐进增强:能用原生 DTK API 表达的走原生,表达不了或更适合 QSS 的走 QSS 桥接;
    • 不破坏 DTK:仅做二次样式覆盖,不改动控件绘制逻辑。

1.3 非目标

  • 不重写/替换 DTK 控件绘制(仍由 DStyle / chameleon 负责)。
  • 不替代 QML 的 Palette {} 类型(DTK CSS 以 Widget/C++ 为主,QML 为可选扩展)。

2. DTK 样式体系调研结论

2.1 模块分层

模块 职责 与样式的关系
dtkcommon 构建基础设施(qmake pri/prf) 新模块沿用
dtkcore 非图形能力(系统信息/文件/日志)
dtkgui 图形基础(无 UI 控件) DPaletteDGuiApplicationHelperDColorDFontSizeManagerDPlatformTheme
dtkwidget QWidget 控件封装 DStyle(继承 QCommonStyle)、DApplication、各 D*控件
dtkdeclarative QML 绑定 可选:Palette {}类型(参考)
qt5integration chameleon 样式插件 D*控件实际由 chameleon 绘制

2.2 关键使能点(为什么 DTK CSS 可行)

DTK 自定义控件DStyle/chameleon 自行绘制,并不依赖 QSS 来渲染自身背景。 因此 QSS 可作为「二次样式」安全使用,不会破坏 DTK 视觉规范——这正是 DTK CSS 能落地的底层基础。

2.3 调色板 DPalette

  • 继承 QPalette,新增 DTK 扩展色角色(DPalette::ColorType):

    • 标准角色:WindowWindowTextBaseTextButtonButtonTextHighlightHighlightedTextAlternateBasePlaceholderText 等;
    • DTK 扩展角色:ItemBackgroundTextTitleTextTipsTextWarningFrameBorder 等。
  • 颜色分组(QPalette::ColorGroup):Normal/ActiveDisabledInactive;控件还有 Hover/Pressed/Focus 等由 DStyle 绘制的状态。

2.4 主题与度量

  • DGuiApplicationHelperColorType(UnknownType=跟随系统 / LightType / DarkType) 管理明暗;切换时发 themeTypeChanged() 信号。

  • DStyle 提供原生度量(部分默认):

    • PM_FrameRadius=8(控件圆角)、PM_TopLevelWindowRadius=18(窗口圆角);
    • PM_ContentsMargins=10、PM_ContentsSpacing=10、PM_FocusBorderWidth=2、PM_ShadowRadius 等。
  • 设置圆角必须用原生 APIDStyle::setFrameRadius(widget, r)(底层写属性 _d_dtk_frameRadius)。QSS 的 border-radius 对 DStyle 自绘背景不生效


3. 总体设计

3.1 模块定位(推荐)

  • 新建独立模块 dtkcss,与 dtkcommon/dtkgui/dtkwidget 同级,依赖 dtkwidget + dtkgui(QML 绑定可选依赖 dtkdeclarative)。
  • 备选方案:并入 dtkwidget 作为 css 子组件(耦合更紧、升级更慢)。推荐独立模块,便于单独发版与测试。

3.2 设计原则

  1. 主题感知:解析时为每个可着色属性生成 Light/Dark 两套调色板,绑定到控件并监听 themeTypeChanged() 实时切换。
  2. 原生优先:圆角、边距、间距、字号、阴影等走 DStyle/DFontSizeManager 原生 API;颜色走 DPalette 角色覆盖。
  3. QSS 桥接兜底hover/pressed/focus 伪类、渐变、背景图等 QSS 原生支持且 DTK 允许二次样式的内容,生成 QSS 规则命中对应控件。
  4. 声明式 + 复用:支持 CSS 变量(--var)、@media 明暗主题块、@theme auto/light/dark

4. CSS 语法规范(草案)

4.1 选择器

  • 控件类选择器:DMainWindowDButtonDLineEditDLabelDSliderDSwitchButton …(也兼容 Qt 标准类如 QPushButton,见待确认问题 5)。
  • 通配:*
  • ID 选择器:#object-name(按 QObject::objectName 命中)。
  • 属性选择器:DLineEdit[warning="true"]
  • 后代/子代:DMainWindow DButton

4.2 伪类(状态)

  • :hover:pressed:disabled:focus:checked(对应控件状态)。
  • 明暗主题用 @media 而不是伪类(见下)。

4.3 主题块



5. 属性映射表(CSS → DTK)

CSS 属性 映射到 适用 备注
background/background-color DPalette角色(Window/Base/Button/ItemBackground,按上下文选) 基础/明暗 生成 Light+Dark 双值
color DPalette文字角色(WindowText/Text/ButtonText) 基础/明暗
border-color DPalette::FrameBorder 基础/明暗
border-width DStyle度量 / QSS 基础
border-radius DStyle::setFrameRadius 基础 必须走原生,QSS 圆角对自绘背景无效
padding/margin PM_ContentsMargins 基础 setProperty
spacing PM_ContentsSpacing 基础
font-size DFontSizeManager等级(T1–T10)或 px 基础
box-shadow DStyle阴影度量(PM_ShadowRadius 等) 基础
opacity setWindowOpacity/setOpacity 基础
background-image/ 渐变 QSS 桥接 基础 DTK 原生不表达
:hover/:pressed/:focus QSS 伪类桥接 状态 QSS 原生支持,DTK 允许二次 QSS
:disabled QPalette::Disabled 状态

6. 架构与核心类

6.1 类设计(命名空间 DTK_CSS_NAMESPACE / DCss

  • DCssParser:词法 + 语法分析,产出 DCssStylesheet(规则列表)。

  • DCssSelector:把选择器编译为匹配器,对 QWidget 做类/objectName/属性/状态匹配。

  • DCssRule / DCssDeclaration:单条规则与声明(含所属 @media、伪类)。

  • DCssApplicator:核心转换器。对目标控件树:

    1. 生成 Light/Dark 双 DPalette 覆盖,绑定控件并随 themeTypeChanged() 切换;
    2. 写入 DStyle 度量(frameRadius / margins / shadow)→ setProperty / DStyle::setFrameRadius
    3. 生成 QSS 字符串 承载 hover/pressed/focus 与渐变/图片等,调用 widget->setStyleSheet()(或应用级 QApplication)。
  • DCssApplicationHelper(单例):loadAppCss(path) / loadAppCssString(str)(应用级);registerWidget(w)(主题切换时重算);监听 DGuiApplicationHelper::themeTypeChanged()

6.2 对外 API(草案)



6.3 数据流


(架构图见对话内联示意)


7. 实现里程碑

阶段 内容 产出
M0 调研 + 本计划书定稿 本文档
M1 模块骨架:dtkcss的 cmake/qmake、pkg-config、DCssApplicationHelper桩、命名空间 可编译空模块
M2 CSS 解析器:tokenizer + parser + AST + 选择器模型 + 单元测试用例 解析库 + 测试
M3 应用器①:DPalette映射(基础色/文字/边框)+ 明暗双调色板 + 主题切换 颜色生效
M4 应用器②:DStyle度量(frameRadius/margins/shadow)+DFontSizeManager 几何/字号生效
M5 应用器③:伪类与 QSS 桥接(:hover/:pressed/:disabled/:focus+ 渐变/图片) 状态/复杂属性生效
M6 应用级加载 API + 示例程序(仿 examples/collections的 demo) 可运行 demo
M7(可选) QML 绑定(dtkdeclarativeCss附加属性) QML 支持
M8 文档 + 集成/验收测试 交付文档与测试

8. 风险与对策

风险 对策
DTK 自定义控件由 chameleon 自绘,部分属性 QSS 不生效 圆角/边距/阴影等走 DStyle原生 API;仅把 QSS 用于其原生支持且 DTK 允许二次样式的伪类/渐变
DTK 5.x 与 6.x API 差异(DThemeManager6.0 废弃) 6.x 的 DGuiApplicationHelperpalette 主线实现,必要时对 5.x 做兼容分支
选择器命中精度(objectName / 继承链 / 标准 Qt 类) 明确匹配规则(类全名匹配 + objectName + 属性),并在文档中标注支持范围
大样式表 + 主题切换的重算性能 缓存 AST,仅主题切换时重算调色板,不重新解析

9. 验收标准

  1. 给定一份示例 CSS,能改变 DButton / DLineEdit / DMainWindow 等的基础背景、文字色、圆角、边距
  2. 切换系统明暗主题时,CSS 中 @media dark 规则自动生效,无需重启应用
  3. :hover / :pressed 状态视觉变化生效
  4. 提供 示例程序(demo)单元/集成测试,且测试通过。
  5. (若做 M7)QML 侧 Css 附加属性可达到同等效果。

10. 待确认问题(请确认或调整)大家都来提提意见吧

  1. 模块形态:新建独立模块 dtkcss(推荐)还是并入 dtkwidget
  2. 目标 DTK 版本:以 DTK 6.x(palette 主线,DThemeManager 已废弃)为准,还是同时兼容 5.x?
  3. 实现策略:混合式(DPalette/DStyle 原生 + QSS 桥接伪类,推荐) vs 纯 QSS 转译 vs 纯原生映射?
  4. 覆盖范围:仅 C++/Widget(推荐先做),还是也要 QML(dtkdeclarative) 绑定(M7)?
  5. 选择器范围:仅 DTK 控件(D*),还是也支持 Qt 标准控件QPushButton 等)?

以上 5 点确认后,本计划书即定稿,进入 M1 开发。

Reply Favorite View the author
All Replies
avatar
𰻞𰻝面
deepin
7 hours ago
#1

大佬做研发,我们吃现成的blush

Reply View the author
avatar
HualetWang
deepin
6 hours ago
#2

dtkdeclarative ?

Reply View the author
avatar
ad1998
deepin
an hour ago
#3
HualetWang

dtkdeclarative ?

jut for fun! dtkdeclarative 更厉害

Reply View the author