目录

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 2.0(v2.0.0 已发布,M1–M8 全部完成;代码已并入 master)

用写网页的方式写 DTK 应用:标准 HTML 定义结构(元素自动映射为 QWidget 控件树),标准 CSS 定义样式(引擎翻译为 DPalette / DStyle / DFontSizeManager / Qt 布局),DTK 负责原生绘制与主题。

  • 引擎:src/css2/(命名空间 Dtk::Css2,公开头 dcss2.h);v1 引擎保留于 src/css/ 共存(双引擎并存,Dtk::Css 与 Dtk::Css2 独立 API)。
  • 方案 C:复用 libcss(MIT,vendor 于 third_party/libcss)的解析前端(事件流 + 原始 token),自研选择匹配/级联/计算值/布局/主题。
  • 能力:HTML 元素→控件映射、选择器 Level 3 全量 + 常用 Level 4、级联(特异性/!important/继承/var())、flex/grid 布局、DPalette 角色、明暗主题(@media)、hover/focus 状态驱动重算、动态 [attr] 自动重算、opacity 过渡。
  • 用法:DtkHtmlWindow + loadDocument(html)(内嵌 <style>)或 loadHtml/loadCss;widgetFor(id) 绑定逻辑。
  • 示例:examples/demo_html(HTML+CSS 设置窗口)、examples/calendar_demo(日历应用,HTML/CSS/逻辑三层分离 + shots 自测 + render 日志)。
  • 开发文档:DTK-CSS-2.0-开发计划书.md、dtk-css skill。
  • 构建依赖:libparserutils/libwapcaplet(pkg-config;deepin 无包时按 docs/spike/2026-08-15-libcss-event-api/README.md 源码构建,静态库需 -fPIC)。

已确认的设计决策(见 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 习惯用法;VERSION 2.0.0,集成 css2 + vendor libcss)
├── dtkcss.pc               # pkg-config 文件(qmake 用)
├── cmake/dtkcss.pc.in      # pkg-config 模板(CMake 用)
├── src/
│   ├── src.pri             # 源/头文件清单(v1 css + 2.0 css2 + vendor libcss)
│   ├── css/                # v1 引擎(命名空间 Dtk::Css,保留兼容)
│   │   ├── dcssglobal.h            # 版本 / 导出宏 / 命名空间
│   │   ├── dcss.h                  # 总包含头
│   │   ├── dcssrule.h/.cpp         # 选择器 / 规则 AST + 匹配
│   │   ├── dcssstylesheet.h/.cpp   # 解析后的样式表
│   │   ├── dcssparser.h/.cpp       # CSS 解析器(纯 Qt,可单测)
│   │   ├── dcsspalette.h/.cpp      # 颜色解析 / var / DPalette 角色映射
│   │   ├── dcssmetrics.h/.cpp      # DStyle 度量 + DFontSizeManager
│   │   ├── dcsspropertyregistry.h/.cpp # 属性注册表(轻量 IR):属性→通道/角色 + 扩展注册 API
│   │   ├── dcsscache.h/.cpp        # 编译结果缓存:双主题 × 状态 palette 快照
│   │   ├── dcssstateengine.h/.cpp  # 状态引擎:事件驱动切换状态调色板,替代 QSS
│   │   ├── dcssapplicator.h/.cpp   # 应用器(编译 + 缓存 + DPaletteHelper 写入)
│   │   └── dcssapplicationhelper.h/.cpp # 应用级入口
│   └── css2/               # 2.0 引擎(命名空间 Dtk::Css2,公开头 dcss2.h)
│       ├── dcss2.h / dcss2global.h       # 总包含头 / 导出宏
│       ├── dcss2token / rule / stylesheet # 词法 token / 选择器 AST / 规则树
│       ├── dcss2parser / frontend / varscan # libcss 解析前端 + --* 变量旁路
│       ├── dcss2dom / widgetmap / htmlwindow # HTML DOM + 元素→控件映射 + DtkHtmlWindow
│       ├── dcss2value / property / cascade / applicator # 级联/继承/计算值/应用器
│       ├── dcss2layout               # flex/grid 布局通道(QBoxLayout/QGridLayout)
│       ├── dcss2theme                # DPalette 角色 / @media 明暗主题
│       └── dcss2stateengine          # 交互状态引擎(hover/focus → 自动重算 + 过渡)
├── third_party/libcss/   # vendor 的 libcss(MIT,NetSurf;仅 lex/parse/charset/utils)
├── examples/
│   ├── demo_html/        # HTML+CSS 设置窗口示例(M7)
│   ├── calendar_demo/    # 日历示例:HTML/CSS/逻辑三层分离 + shots 自测 + render 日志
│   └── demo/             # v1 示例
├── docs/
│   ├── skill/dtk-css/    # dtk-css Skill(SKILL.md + references + evals,7 用例)
│   ├── spike/            # 技术 spike 记录(libcss 事件 API,2026-08-15)
│   └── architecture-review.md
└── tests/
    ├── test_*.cpp        # v1 引擎 8 测试(parser/palette/metrics/state/cascade/selector/registry/integration)
    ├── test_css2_*.cpp   # 2.0 引擎 9 测试(parser/selector/varscan/dom/widgetmap/cascade/layout/theme/state)
    ├── CMakeLists.txt
    └── *.pro             # qmake 单测工程
├── 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.2.0.0、dtkcss.pc。 第三方应用通过 pkg-config 使用:

// main.cpp
#include <dtkcss/dcss.h>
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/dcss.h>
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 中跑构建与全部测试。
关于

为 linuxdeepin 的dtk 添加css 界面开发能力

662.0 KB
邀请码
    Gitlink(确实开源)
  • 加入我们
  • 官网邮箱:gitlink@ccf.org.cn
  • QQ群
  • QQ群
  • 公众号
  • 公众号

版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9 京公网安备 11010802047560号