[DTK] dtkcss 为 DTK 应用增加 **“用 HTML/CSS 设计界面”** 的能力。
Tofloor
poster avatar
ad1998
deepin
2026-08-13 13:37
Author

dtkcss — DTK CSS 样式引擎

为 DTK(Deepin ToolKit)应用增加 “用 CSS 设计界面” 的能力。一份接近 Web CSS 的样式表,
由引擎翻译为 DTK 原生的 DPalette / DStyle / DFontSizeManager 以及事件驱动的状态调色板,
从而兼顾明暗主题、控件状态(hover/pressed/disabled/focus)与 DTK 视觉规范。

本模块是 DTK 上游功能的 提案实现原型,目标 DTK 6.x(palette 主线,DThemeManager 已废弃)。
已弃用 QSS:状态与复杂样式不再走 setStyleSheet,全部落在 DPalette/DStyle 原生通道。


已确认的设计决策(见 DTK-CSS-开发计划书.md)

# 决策 结果
1 模块形态 独立模块 dtkcss
2 目标 DTK 版本 DTK 6.x(不主动兼容 5.x)
3 实现策略 混合式(原生 + 状态引擎,弃用 QSS)
4 覆盖范围 仅 C++/Widget(QML 暂不做)
5 选择器范围 同时支持 DTK 控件(D*)与 Qt 标准控件(QPushButton 等)

目录结构

dtkcss/
├── CMakeLists.txt          # CMake 构建(Qt5/Qt6 + pkg-config DTK)
├── dtkcss.pro              # qmake 构建(DTK 习惯用法)
├── dtkcss.pc               # pkg-config 文件(qmake 用)
├── cmake/dtkcss.pc.in      # pkg-config 模板(CMake 用)
├── src/
│   ├── src.pri             # 源/头文件清单
│   └── css/                # 库源码(命名空间 Dtk::Css)
│       ├── dcssglobal.h            # 版本 / 导出宏 / 命名空间
│       ├── dcss.h                  # 总包含头
│       ├── dcssrule.h/.cpp         # 选择器 / 规则 AST + 匹配
│       ├── dcssstylesheet.h/.cpp   # 解析后的样式表
│       ├── dcssparser.h/.cpp       # CSS 解析器(纯 Qt,可单测)
│       ├── dcsspalette.h/.cpp      # 颜色解析 / var / DPalette 角色映射(M3)
│       ├── dcssmetrics.h/.cpp      # DStyle 度量 + DFontSizeManager(M4,已接线)
│       ├── dcsspropertyregistry.h/.cpp # 属性注册表(轻量 IR):属性→通道/角色 + 扩展注册 API
│       ├── dcsscache.h/.cpp        # 编译结果缓存:双主题 × 状态 palette 快照(M5)
│       ├── dcssstateengine.h/.cpp  # 状态引擎:事件驱动切换状态调色板,替代 QSS(M5)
│       ├── dcssapplicator.h/.cpp   # 应用器(编译 + 缓存 + DPaletteHelper 写入)
│       └── dcssapplicationhelper.h/.cpp # 应用级入口
└── tests/
    ├── test_parser.cpp     # Qt Test 单元测试(解析器)
    ├── test_palette.cpp    # 颜色映射 / 角色 / var 测试(M3)
    ├── test_metrics.cpp    # 度量通道测试(M4)
    ├── test_state.cpp      # 双主题快照 / 状态引擎测试(M5)
    ├── test_cascade.cpp    # 层叠/特异性/!important/padding/reload 测试
    ├── test_selector.cpp   # '>' 子代 / :not() / 类型索引 / spacing 测试
    ├── test_registry.cpp   # 属性注册表 / 动态属性失效测试
    ├── test_integration.cpp # M8 集成/验收测试(端到端 helper 流程)
    ├── CMakeLists.txt
    └── test_parser.pro
├── scripts/ci-build.sh    # CI 依赖安装 + 构建 + 测试脚本(Deepin 23)
└── .github/workflows/ci.yml # GitHub Actions(deepin:beige 容器)

构建

⚠️ 实际编译需要 Linux + DTK 6.x 开发环境(deepin 23 / UOS,或装有 dtkwidget-dev、dtkgui-dev
的构建机)。Windows 下无法构建 DTK,本仓库仅作为源码与原型交付。

qmake

qmake dtkcss.pro
make
sudo make install

CMake

mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/usr
make
ctest --output-on-failure   # 运行全部单元/集成测试
sudo make install

安装与消费(发版验证通过)

安装后产物:/usr/include/dtkcss/*.h、libdtkcss.so.1.0.0、dtkcss.pc。
第三方应用通过 pkg-config 使用:

// main.cpp
#include 
g++ main.cpp $(pkg-config --cflags --libs dtkcss) -o app

scripts/ci-build.sh 可在任意 Deepin 23 环境一键构建 + 测试;qmake 与 CMake
两条构建路径均验证通过(qmake dtkcss.pro && make)。


API 用法(草案)

#include 
DTKCSS_USE_NAMESPACE

// 应用级(在 DApplication 之后调用)
DCssApplicationHelper::instance()->loadAppCss(":/style/app.css");
// 注册窗口:其控件树应用样式,并在明暗主题切换时自动重应用
DCssApplicationHelper::instance()->registerWidget(mainWindow);

// 单控件级
DCssApplicator::applyString(
    "DButton { background: #0081ff; color: white; border-radius: 12px; }",
    myButton);

支持的 CSS 语法(子集)

@theme auto;                 /* auto=跟随系统 / light / dark */

:root {
  --brand: #0081ff;
  --radius: 8px;
}

DMainWindow { background: #f8f8f8; }

DButton {
  background: #e5e5e5;       /* → DPalette::Button */
  color: #000;               /* → DPalette::ButtonText */
  border-color: #d0d0d0;     /* → DPalette::FrameBorder */
  border-radius: var(--radius); /* → DStyle::setFrameRadius(原生,M4 实现) */
  font-size: T6;             /* → DFontSizeManager::T6(M4 实现) */
  padding: 6px 12px;         /* → M5 QSS 桥接 (暂未实现) */
}

DButton:hover  { background: #dcdcdc; }   /* → 状态引擎:hover 进入时切换 palette 快照 */
DButton:pressed{ background: #d0d0d0; }   /* → 状态引擎:pressed 快照 */
DButton:disabled { background: #f0f0f0; color: rgba(0,0,0,.3); } /* → QPalette::Disabled 组 */

#login-btn { background: var(--brand); }  /* 按 objectName 命中 */

/* 暗色主题覆盖 */
@media (prefers-color-scheme: dark) {
  DButton { background: #444; color: #fff; }
}

选择器:DButton / QPushButton(类,含基类匹配)、#id(objectName)、
[attr="val"](动态属性)、DMainWindow DButton(后代)、DMainWindow > DButton(子代)、
:not(QPushButton) / :not(#id) / :not([attr])(排除)、:hover/:pressed/:disabled/:focus/:checked(伪类,状态引擎)。


开发状态

阶段 内容 状态
M0 调研 + 计划书定稿 ✅
M1 模块骨架(构建/pkg-config/命名空间/头骨架) ✅
M2 CSS 解析器(tokenizer/parser/AST/选择器/单测) ✅
M3 应用器①:DPalette 映射 + 明暗双调色板 + 主题切换 ✅
M4 应用器②:DStyle 度量(frameRadius/padding)+ DFontSizeManager(T1–T11 / px) ✅
M5 应用器③:状态引擎(弃用 QSS) + 双主题快照缓存 ✅
M6 应用级加载 API + 示例 demo ✅
M7 QML 绑定(暂不做) ⏸
M8 文档 + 集成/验收测试 + CI ✅

当前(M1–M5)已完成:

  • M1+M2:可解析 CSS 并产出 AST(DCssStylesheet),可在不含 DTK 的环境下用
    tests/test_parser 对解析器做单元测试;
  • M3:把解析结果真正落地到控件——颜色属性映射到 DPalette(标准 QPalette 角色 +
    DTK 扩展角色 ItemBackground/TextTitle/TextTips/TextWarning/FrameBorder 等),
    支持 @media dark/light 与 @theme 的明暗过滤;
  • M4:border-radius → DStyle::setFrameRadius,font-size → DFontSizeManager
    (T1–T11 / px),padding(1–4 值简写)→ QWidget::setContentsMargins,
    经 DCssApplicator 的 metric 通道落地;
  • M5:弃用 QSS。:hover/:pressed/:focus/:checked 由 DCssStateEngine 事件驱动切换
    预编译的 palette 快照(经 DPaletteHelper 写入,扩展角色不丢失);:disabled 编译进
    QPalette::Disabled 组由 DTK 原生绘制;DCssStyleCache 缓存每控件双主题快照,
    主题切换走 applyCached 零重算;
  • 层叠语义(W3C):声明按 !important > 特异性(id > class/attr/伪类 > 类型)> 文档顺序
    排序应用(tests/test_cascade 覆盖);DCssApplicationHelper::reload() + QFileSystemWatcher
    支持样式表热重载。
  • 选择器扩展:> 子代组合器、:not()(单复合参数,参数计入特异性);DCssStylesheet
    按 subject 类型建索引,rulesFor 只评估类链桶 + 泛型桶,替代全量扫描
    (tests/test_selector 覆盖);spacing → 布局 setSpacing。
  • 属性注册表(轻量 IR):CSS 属性 → 通道(Palette/Metric)与目标角色的声明式映射表,
    替代 dcssApplyColor 的 if-else 链;dcssRegisterProperty() 支持注册自定义属性
    (开闭原则);动态属性 [attr=...] 变化自动失效并重算(DCssStyleCache::styleDirty),
    objectName 运行时变更用 DCssApplicationHelper::refreshWidget() 手动刷新
    (tests/test_registry 覆盖)。
  • M8 验收:tests/test_integration 端到端覆盖计划书验收标准——基础背景/文字色/圆角/padding、
    真实 setPaletteType 主题切换(@media dark 免重启生效)、:pressed 状态、注册/加载顺序;
    scripts/ci-build.sh + GitHub Actions(deepin:beige 容器)在 CI 中跑构建与全部测试。
Reply Favorite View the author
All Replies
avatar
𰻞𰻝面
deepin
2026-08-13 14:13
#1

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

Reply View the author
avatar
HualetWang
deepin
2026-08-13 14:48
#2

dtkdeclarative ?

Reply View the author
avatar
ad1998
deepin
2026-08-13 19:42
#3
HualetWang:

dtkdeclarative ?

jut for fun! dtkdeclarative 更厉害

Reply View the author
avatar
zccrs
deepin
2026-08-13 20:56
#4

建议用dtkdeclarative

Reply View the author
avatar
ad1998
deepin
2026-08-16 17:41
#5

https://www.gitlink.org.cn/ltree/dtkcss 代码已更新, 祝大家vibe 快乐!

Reply View the author