项目简介
能在软件运行时对 CSS 样式表主题(包罗 SVG 资源和 SVG 图标)举行及时颜色切换的Qt项目。
项目预览:
项目地点
地点:Qt-Advanced-Stylesheets
本地编译情况
Win11 家庭中文版
Qt5.15.2 (MSVC2019)
Qt Creator15.0.1
本地编译
克隆到本地后,直接利用Qt Creator打开.pro,选择full_features项目编译运行即可。
一键换肤功能解析
一键换主题皮肤怎样实现?
起首通过.ui文件可以看到,利用的都是Qt提供的标准控件,无其他自定义控件:
风格主配置文件:./styles/qt_material/material.json
紧张定义程序图标、完备CSS文件、主题、图标颜色以及调色版palette干系配置。
主题配置文件:./styles/qt_material/themes/*.xml
配置dark、light主题及其下各级标题的颜色。
完备CSS文件:./styles/qt_material/material.css.template
就是配置界面中控件样式,不过颜色确实根据不同主题配置文件中定义的颜色变量。
至此可以确认一键换肤的大致实现框架:风格 -> 主题 -> CSS样式
①读取风格主配置文件 (./styles/qt_material/material.json),加载对应的程序图标、CSS样式、默认主题以及调色板干系配置。
②读取默认主题配置文件 (./styles/qt_material/themes/dark_teal.xml),获取各级主题对应色值配置。
③读取CSS文件,应用②中读取色值并实际应用控件样式。
④对于当前风格(即./styles/qt_material),切换不同主题则加载对应主题配置文件(./styles/qt_material/themes/*.xml),再刷新CSS样式,即用户每次手动切换主题,重复②、③步调。
⑤**按现有框架计划,还可扩展实现风格(style)切换功能。**现在只有一种(即./styles/qt_material),后可扩展实现切换风格(style)功能,每次切换style,则重新加载风格主配置文件、读取该风格默认主题配置文件、再应用CSS样式。即用户每次手动切换风格,重复①、②、③步调。
接着通过代码验证下上述逻辑:
可直接在主窗口构造函数中看到上述逻辑的接口调用:
- CMainWindow::CMainWindow(QWidget *parent)
- : QMainWindow(parent),
- d(new MainWindowPrivate(this))
- {
- d->ui.setupUi(this);
- QString AppDir = qApp->applicationDirPath(); //获取程序运行目录
- QString StylesDir = STRINGIFY(STYLES_DIR); //获取风格目录,STYLES_DIR在full_feature.pro中定义:DEFINES += "STYLES_DIR=$$PWD/../../styles"
- d->AdvancedStyleSheet = new acss::QtAdvancedStylesheet(this); //封装的风格主题样式类
- d->AdvancedStyleSheet->setStylesDirPath(StylesDir); //设置风格目录
- d->AdvancedStyleSheet->setOutputDirPath(AppDir + "/output"); //设置程序风格主题样式类资源的输出目录
- d->AdvancedStyleSheet->setCurrentStyle("qt_material"); //设置当前风格
- d->AdvancedStyleSheet->setDefaultTheme(); //设置当前风格的默认主题
- d->AdvancedStyleSheet->updateStylesheet(); //确定风格主题后更新整体样式
- setWindowIcon(d->AdvancedStyleSheet->styleIcon()); //设置风格配置中的默认程序图标
- qApp->setStyleSheet(d->AdvancedStyleSheet->styleSheet()); //应用CSS
- connect(d->AdvancedStyleSheet, SIGNAL(stylesheetChanged()), this, //切换风格信号和槽连接
- SLOT(onStyleManagerStylesheetChanged()));
- d->createThemeColorDockWidget();
- d->fillThemeMenu();
- d->setSomeIcons();
- d->setupQuickWidget();
- d->loadThemeAwareToolbarActionIcons();
- }
复制代码
这里还想再提一下的是,CSS中的勾选框、复选框之类的控件样式,有些是通过设置svg图标实现的,在切换主题是可以发现图标颜色也发生了变革:

切换后:

说明图标有发生变革,通过切换前后对比,可以发现确实图标确实有发生变革:

切换后:

代码中是通过封装的CSVGIconEngine(继续自QIconEngine)实现的:
- // SVG颜色替换核心逻辑
- void QtAdvancedStylesheet::replaceSvgColors(QByteArray& SvgContent, const tColorReplaceList& ColorReplaceList) {
- const auto& ReplaceList = ColorReplaceList.isEmpty() ? d->iconColorReplaceList() : ColorReplaceList;
- for (const auto& Replace : ReplaceList) {
- d->replaceColor(SvgContent, Replace.first, Replace.second); // 直接替换二进制数据
- }
- }
- // 动态更新所有图标颜色
- void CSVGIconEngine::updateAllIcons() {
- for (auto Engine : *IconEngineInstances) {
- Engine->update(); // 重新调用replaceSvgColors
- }
- }
复制代码 通过自定义图标引擎(CSVGIconEngine)和颜色更换逻辑(replaceSvgColors),结合风格主配置文件(./styles/qt_material/material.json)中的"icon_colors"配置的颜色映射,实现了SVG图标的动态颜色切换。
当主题变革时,所有图标会自动更新,无需重新加载文件。
总结
通过对Qt-Advanced-Stylesheets源码阅读及本地调试,剖析了Qt-Advanced-Stylesheets项目一键动态切换主题功能的焦点实现,即通过不同的 风格 -> 主题 -> 样式 配置架构管控软件整体风格样式。
必要注意的是控件干系样式设置需在CSS文件中配置,若在代码或ui文件中设置会无法动态切换,同时必要注意css文件中的颜色值必要通过颜色模板变量而不是详细数值设置。
而对于混框架(如Qt + MFC)大型项目的一键切换风格主题样式,可否鉴戒该实现方式,有待商榷。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |