Union QtWidgets 的首次发布
摘要
Union Widgets 的首次发布允许基于 Qt 的应用程序使用 CSS 文件进行样式设置,旨在统一 KDE Plasma 中 QtQuick 和 QtWidgets 的样式。作者讨论了技术挑战以及针对 Plasma 6.8 版本的即将修复。
<p><a href="https://lobste.rs/s/rv7z2p/initial_release_union_qtwidgets">评论</a></p>
查看缓存全文
缓存时间: 2026/08/29 07:47
# Union QtWidgets 初始版本发布 | AksDev
来源:https://akselmo.dev/posts/union-qtwidgets/
项目启动啦!
经过数月的工作,我终于成功将Union (https://invent.kde.org/plasma/union/-/commit/0131e503787c77620e5bad2390165247590d1cf7) 的 QtWidgets 部分拼凑出来。
这意味着您的 QtWidgets 应用程序(例如 Dolphin、KMail、Kate 等)现在可以使用 Union CSS 文件作为其样式的来源。
**但是,请降低期望值,因为这仅仅是首个初始版本!**
[](https://akselmo.dev/assets/images/unionwidgets/dolphin.png)[](https://akselmo.dev/assets/images/unionwidgets/demo1.png)[](https://akselmo.dev/assets/images/unionwidgets/demo2.png)[](https://akselmo.dev/assets/images/unionwidgets/demo3.png)
我的蜥蜴形象摆出微笑脸。
请注意,存在一些视觉错误和怪异之处!我仍在继续工作中!
是的,正如您所见,有些地方看起来不太对劲。完全不像 Breeze!有些地方只是有所不同,有些地方颜色则出错了。
这些问题都是可以修复的,我将尽最大努力在 Plasma 6.8 发布前修复尽可能多的问题。
但一些其他怪异之处是意料之中的:这是有史以来第一次,Breeze QtWidgets 和 QtQuick 样式拥有**共享的、易于编辑的单一真实来源**!(不包括颜色方案。)因此,其中一些设计是针对 QtQuick 构思的,所以在 QtWidgets 中看起来可能会有点别扭。
我将在此说明我做了什么以及仍需完成的工作,但这是一个巨大的工程,所以我打算为这个首次版本小小的庆祝一下。:)
## 等等,我能试试看吗? (https://akselmo.dev/posts/union-qtwidgets/#hold-on-can-i-try-it)
当然可以!除非有人反对,否则它应该会在 Plasma 6.8 中发布。就目前所知,还没有人提出异议。
您也可以创建自己的 CSS 文件,并观察它们如何影响 QtWidgets 应用程序。请预料到一些兼容性问题,并报告所有错误!
尽情尝试主题吧。尝试一切。让奇思妙想重返计算机。告诉我们您的主题体验如何。
**玩得开心。** 您的计算机应该和您本人一样酷。
这篇博文的剩余部分更多是技术性的絮叨,我在抒发对这个项目的疲惫感,哈哈。
## QStyle 很困难 (https://akselmo.dev/posts/union-qtwidgets/#qstyle-is-difficult)
QStyle 主题——用于修改 QtWidgets 应用程序外观的样式——并不容易处理。我见过的大多数主题都是基于现有的主题(如 Fusion 或 Breeze)进行修改。
但对于 Union,我们必须从头开始。我采用了 QStyle 的基础——称为 QCommonStyle(一种类似后备主题的东西),然后在此基础上开始构建。
接着,涉及多个部分:
- 找到一种让 QStyle 使用 CSS 绘制元素的方法
- 通过读取 CSS 数据并将其应用到 QStyle 的世界中,来构建样式的层级结构
- 创建一套全新的元素文件(我们使用这些文件),否则 QStyle 主题将会非常笨重且难以处理
- 逐一检查*每一个元素*,确保它们能正确读取 CSS 中的所有数据——并确保样式保持向后兼容!——这仍然是一个持续进行的过程,大多数 bug 都潜伏在这里。:P
- 搞清楚如何在 QStyle 元素中使用 Union 的布局系统——这也有 bug,因为 QStyle 的布局更加“死板”——应用程序多年来一直期望 QStyle 提供非常特定的布局——因此任何偏离这些期望的应用程序看起来都会出问题
- 实现缓存以保证性能——在这里 Arjen 给了我很大帮助,谢谢你!
- 还有很多其他我已经忘记的事情...
幸运的是 redstrate (https://redstrate.com/) 已经为一个非常简化的 proxystyle(它修改了 Breeze)实现了绘制部分,所以我无需对其进行太多修改。我主要是调整它以配合我的层级系统工作。所以谢谢! <3
很难用语言形容涉及实际 QStyle 本身以及创建一种“框架中的框架”(以便 Union 规则能更好地转换为 QStyle 规则)的工作量有多大。
例如,当一个控件(如 QPushButton)想要被样式化时,它会通过一种叫做 `QStyleOptionButton` 的东西通知 QStyle。这个类包含了关于按钮的大量信息,样式可以利用这些信息来更好地装饰它。但是,当然,styleoption 不一定必须存在。如果没有 styleoption,样式可以使用 `QWidget` 本身获取样式信息。但即使是它也可能为空!那时,你就不知道该如何样式化某个东西了,因为你甚至不知道它是什么。
更糟糕的是,相关文档根本不存在。
当然,有 QStyle (https://doc.qt.io/qt-6/qstyle.html) 文档,但它更多是关于“是什么”而不是“为什么”或“如何”。我本可以找一些关于如何从头开始制作 QStyle 的教程,但我几乎找不到任何相关资料,只有一些来自 Qt4 时代的超旧信息。所以,非常非常频繁地,我只能直接阅读原始源代码,而源代码本身也不太容易阅读。有很多变量只是命名为 `pw` 或 `w`。所以连代码库本身也严重缺乏文档记录!
大部分工作不得不通过试错来完成!“如果我改变这个值会怎样?”“如果我用调试器跟踪这个变量,它会通向哪里?”我也经常把 Breeze 作为我的信息库,因为它经历过所有这些。那非常有帮助。
但是,缺乏文档以及似乎已无人维护(更不用说记录)的古老代码库,才是导致这一切耗时如此之长的根本原因。
我的蜥蜴形象摆出暴躁脸。
更不用说 API 中那些完全误导性的名称了。“PM_MenuPanelWidth” 并不是面板的宽度,而实际上是“应用于所有边框的 QMenu 边框宽度”。
总工作量是 9000 行代码。没错。并且全部都是必需的。很多样板代码,因为 QStyle 似乎偏爱样板代码。几乎全部是由本人手工编写的、精心打磨的“手工艺品”。
我不得不煞费苦心地逐一检查我们绘制的所有元素和计算的所有尺寸,然后将它们转换成一个 `Element`,这样我们就能在不修改整个样式的情况下轻松地修改它。
如果您设法从头开始制作一个完全可用的 QStyle 主题,处理过每一个小细节,我向您致敬。**这是我经历过的最困难的工作之一。**
总结一下:我不得不逆向工程很多东西,才能弄清楚我们绘制某些东西的顺序是什么,或者在实际应用中什么尺寸影响什么。然后使其与 Union 核心和 CSS 配合工作。
我的蜥蜴形象摆出尖叫脸。
拜托了,请给您的 API 写文档!
## 后续步骤 (https://akselmo.dev/posts/union-qtwidgets/#next-steps)
接下来是测试和修复 bug。
这里已经发现了很多 bug:https://invent.kde.org/plasma/union/-/work_items/205 ,并且还会发现更多。会出现一些奇怪的边缘情况,因为应用程序期望一切都像 Fusion 样式(它是默认的 Qt 样式)那样工作,但 Union 尚未很好地处理这些情况。
所以,亲爱的读者,这就是我需要你们做的:看看哪些地方坏了。记录下来。提交错误报告 (https://bugs.kde.org/)。让我们找出这些奇怪的问题并解决它们,以便 QtWidgets 端最终能够不那么痛苦地进行主题化。
当然,还有设计方面的问题:如我之前提到的,我们现在有的 Breeze CSS 非常面向 QtQuick,因此 QtWidgets 应用程序看起来和感觉上可能会有些奇怪。
不过,需要记住的是,由于 QtQuick 和 QtWidgets 的工作和绘制方式不同,它们可能永远无法看起来完全相同。但我们可以先努力让 QtWidgets 样式可靠地工作,然后尝试让它看起来尽可能接近 QtQuick 一侧。
我的待办事项清单大致如下:
- 在 6.8 发布前修复尽可能多的 bug
- 为 QStyle 设计一个健壮的布局系统——即使它无法做到 QtQuick 的所有技巧
- 确保 QStyle 与尽可能多的应用程序保持向后兼容
所以,更多的工作。大量的工作。
但至少我们现在可以正式开始这项工作了,这就是这次首次版本发布的意义所在。摆脱那些乏味的工作,让有趣的部分得以开始。
天呐,这工作真是枯燥。我再也不想重来一次了,但老实说...有时也*挺有意思*的。弄明白这一切非常有趣。就像一个非常困难的谜题游戏。我对目前取得的成果感到高兴,即使它还不完美。我希望所有这些工作对你们也有用,亲爱的用户们。我真的很期待看到你们想出的疯狂点子。
感谢阅读!
*ps. 如果这篇文章读起来有些散乱,再次抱歉,我只是需要把它从我的脑子里倒出来。*我不太喜欢写草稿,所以我直接写下来,然后发布。***
相似文章
本周 Plasma 更新:每个屏幕的虚拟桌面与 Wayland 会话恢复
KDE Plasma 6.7 引入了每个屏幕的虚拟桌面、Wayland 会话恢复以及大量 UI 改进,这些改进是在格拉茨举行的年度 KDE 大冲刺之后实现的,包括日历应用配置、Alt+Tab 定位选项和应用操作收藏。
KDE Plasma 6.7 发布
KDE Plasma 6.7 已发布,引入了按屏幕虚拟桌面、麦克风音量测试、长按特殊字符、浅色/深色模式切换、越南农历、系统托盘中的后台应用、打印改进以及各种可用性增强。
KDE Android 新闻 (2026年6月)
KDE Android 应用已更新至 Qt 6.11,改进了安全区域处理,增强了通知功能,并修复了各种问题。
Oxygen 6.7 发布:为 KDE 经典主题带来清新气息
Oxygen 6.7 为 KDE 的经典 Oxygen 主题带来了重要的修复和图标更新,通过社区协作以及原设计师 Nuno Pinheiro 的参与使其焕然一新。
为KDE Plasma最后一个支持X11的版本做准备
KDE宣布Plasma 6.8将放弃X11会话支持,在经历15年开发后完全过渡到Wayland。这一变化仅影响Plasma桌面本身;XWayland支持仍保留用于传统应用程序。