Qt加载.css/.qss文件设置控件的QSS样式(支持程序运行时修改且立即生效类似换肤效果)

初学Qt时,你是如何设置QWidget,QPushButton等原生基础控件的样式的?是不是主要是两种方法?

1.直接在可视化的.ui文件中直接添加qss语句。

2.在代码中通过setStyleSheet(QString qss)来设置qss语句。

上述两种方法,在程序规模很大时,很多地方需要复用样式会非常麻烦,qss语句写的到处都是,极难维护,要你改一个按钮样式你都要到处翻,还要一个个改,烦到想死!

于是,

为了更好地管理样式,提高复用率,应该把QSS样式语句写在一个个文件中(文件后缀是.css或者.qss都可以,但是建议保存为.css文件好点,因为Notepad++可以进行语法识别高亮提醒,另外样式相关的文件编码最好是UTF-8带BOM),程序初始化时统一加载到主程序中,这样所有控件都会自动继承,且通过属性过滤器决定哪个控件生效(如下图)。

我喜欢根据Qt原生支持QSS语句改变样式的基础控件都单独一个.css文件,例如QPushButton.css、QWidget.css、QLabel.css等。。。你也可以根据你自己程序的每个窗口一个.css文件,随你喜欢,我只是给你一种加载样式的思路。

.css文件在Notepad++中能被识别获得语法高亮,自动补全的支持,但是.qss不行

样式根文件StyleList.txt(文件名随意改)负责记录这些所有的.css文件名

这样通过读取样式根文件“StyleList.txt” 即可知有多少个.css/.qss样式文件可以加载,然后对这些样式文件一个个读取,然后将所有内容拼接成一个超长的QString,再使用setStyleSheet(QString qss)来设置加载到主程序中。期间也可以选择性使用QFileSystemWatcher来监控这些样式文件的内容变化,一旦有内容更新会发出信号,然后马上重新加载所有样式。

举例,我一个测试程序的exe文件在bin目录下,bin同级目录下有res/QSS来存放QSS样式相关文件

创建一个加载qss样式的工具类 “QssLoadTool” 用于加载,并监控这些文件的变化:

qssloadtool.h

#ifndef QSSLOADTOOL_H
#define QSSLOADTOOL_H#include <QObject>
#include <QFile>
#include <QFileSystemWatcher>class QssLoadTool : public QObject
{Q_OBJECT
public:explicit QssLoadTool(QObject *parent = nullptr);// 设置qss样式文件的根文件(根文件记录了需要加载的所有qss样式文件名)static void setQssFileListRootFile(const QString &QssRootFile);static QString getQssFileListRootFile();// 加载所有qss文件刷新程序控件样式static void LoadQss2RefreshStyle();// 监控qss相关文件,发送修改就重新加载(在main调用一次即可)static void WatchQSSFileChange(QFileSystemWatcher *FileWatcher);private :// 本程序所需qss样式文件的根文件static QString m_QssRootFile;// 程序运行位置static QString m_currentPath;
};#endif // QSSLOADTOOL_H

qssloadtool.cpp

#include "qssloadtool.h"
#include <QDebug>
#include <QApplication>QString QssLoadTool::m_QssRootFile = "";QssLoadTool::QssLoadTool(QObject *parent) : QObject(parent)
{// 获取应用程序当前路径m_currentPath = QCoreApplication::applicationDirPath();
}void QssLoadTool::setQssFileListRootFile(const QString &QssRootFile)
{m_QssRootFile = QssRootFile;
}QString QssLoadTool::getQssFileListRootFile()
{return m_QssRootFile;
}void QssLoadTool::LoadQss2RefreshStyle()
{if(m_QssRootFile.isEmpty()){qDebug() << "未设置qss样式文件的根文件:" << m_QssRootFile;return;}qDebug() << __FUNCTION__ << "qss样式发送变更,正在重新加载...";QFile file(m_QssRootFile);if (file.open(QIODevice::ReadOnly)){QString style = file.readAll();file.close();QStringList styleList = style.split("\n");style.clear();QString path = "";for(const QString &qssfile : styleList){path = m_currentPath + "/../res/QSS/" + qssfile;file.setFileName(path.trimmed());if(file.open(QIODevice::ReadOnly)){style = style + file.readAll().trimmed();file.close();}else{qDebug() << "打开文件失败! ---> " << path;}}qobject_cast<QApplication*>(QApplication::instance())->setStyleSheet(style);}
}void QssLoadTool::WatchQSSFileChange(QFileSystemWatcher *FileWatcher)
{if(m_QssRootFile.isEmpty()){qDebug() << "未设置qss样式文件的根文件:" << m_QssRootFile;return;}FileWatcher->addPath(m_QssRootFile);qDebug() << "监控qss样式文件的根文件:" << m_QssRootFile;QFile file(m_QssRootFile);if (file.open(QIODevice::ReadOnly)){QString files = file.readAll();file.close();QStringList fileList = files.split("\n");QString path = "";for(const QString &qssfile : fileList){path = m_currentPath + "/../res/QSS/" + qssfile;FileWatcher->addPath(path.trimmed());qDebug() <<"监控qss样式文件 :" << path.trimmed();}}// 被监控的qss文件发生修改时,马上重新加载所有qss样式文件QObject::connect(FileWatcher, &QFileSystemWatcher::fileChanged, [](){QssLoadTool::LoadQss2RefreshStyle();});
}

main.cpp中使用方式:

int main(int argc, char *argv[])
{QApplication a(argc, argv);// 获取exe所在位置(用于拼接样式根文件的相对路径)QString currentPath = QCoreApplication::applicationDirPath();// 设置样式根文件QssLoadTool::setQssFileListRootFile(currentPath + "/../res/QSS/StyleList.txt");// 通过上一步设置的样式根文件去加载每一个.css样式文件QssLoadTool::LoadQss2RefreshStyle(); // 监控所有样式文件的内容变化,一旦发生变化就马上刷新样式并生效// (如果不想监控,那就接下来的这两句代码不写)QFileSystemWatcher fileWatcher;QssLoadTool::WatchQSSFileChange(&fileWatcher);// 主界面启动ProjectMainWindow w;w.show();return a.exec();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/786756.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构】你知道波兰表达式和逆波兰表达式吗?我才知道原来栈在表达式求值中还能这样使用……

栈在表达式求值中的应用 导读一、表达式的形式二、波兰表达式与逆波兰表达式三、表达式之间的相互转换四、栈实现波兰表达式4.1 问题分析4.2 问题完善4.3 算法实现4.3.1 获取波兰表达式4.3.2 从右往左扫描表达式4.3.3 遇到操作数进行入栈操作4.3.4 遇到操作符进行对应操作4.3.5…

Qt元对象系统

第二章Qt元对象系统 文章目录 第二章Qt元对象系统1.什么是元对象&#xff1f;2.元对象系统组成3.信号与槽信号和槽的本质绑定信号与槽自定义槽定义槽函数必须遵循一下规则槽函数的类型自定义槽案例 自定义信号自定义信号需要遵循以下规则信号和槽重载二义性问题 4.内存管理1. 简…

原生小程序开发性能优化指南

性能优化指南 1.骨架屏 业务可以在数据加载完成之前用骨架屏幕来占位&#xff0c;提升体验。 2.包大小优化 减小包中静态资源&#xff0c;例如图片文件&#xff0c;可将图片进行压缩降低文件体积。无用文件、函数、样式剔除。除了部分用于容错的图片必须放在代码包&#xf…

了解游戏相关知识

个人笔记&#xff08;整理不易&#xff0c;有帮助点个赞&#xff09; 笔记目录&#xff1a;学习笔记目录_pytest和unittest、airtest_weixin_42717928的博客-CSDN博客 个人随笔&#xff1a;工作总结随笔_8、以前工作中都接触过哪些类型的测试文档-CSDN博客 目录 一&#xff1a…

MySQL常见故障案例与优化介绍

前言 MySQL故障排查的意义在于及时识别并解决数据库系统中的问题&#xff0c;确保数据的完整性和可靠性&#xff1b;而性能优化则旨在提高数据库系统的效率和响应速度&#xff0c;从而提升用户体验和系统整体性能。这两方面的工作都对于保证数据库系统稳定运行、提升业务效率和…

加域报错:找不到网络路径

在尝试将计算机加入Windows域时&#xff0c;如果收到“找不到网络路径”的错误提示&#xff0c;可能的原因及解决方法如下&#xff1a; 网络连接问题&#xff1a;确保计算机与域控制器之间的物理网络连接是正常的&#xff0c;可以通过ping命令测试与域控制器的连通性。例如&…

LeetCode 56. 合并区间

以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区间 。 示例 1&#xff1a; 输入&#xff1a;intervals [[1,3…

HarmonyOS 应用开发之LifecycleService接口切换LifecycleData接口切换

LifecycleService接口切换 FA模型接口Stage模型接口对应d.ts文件Stage模型对应接口onStart?(): void;ohos.app.ability.ServiceExtensionAbility.d.tsonCreate(want: Want): void;onCommand?(want: Want, startId: number): void;ohos.app.ability.ServiceExtensionAbility.…

c# 插值搜索-迭代与递归(Interpolation Search)

给定一个由 n 个均匀分布值 arr[] 组成的排序数组&#xff0c;编写一个函数来搜索数组中的特定元素 x。 线性搜索需要 O(n) 时间找到元素&#xff0c;跳转搜索需要 O(? n) 时间&#xff0c;二分搜索需要 O(log n) 时间。 插值搜索是对实例二分搜索的改进&#xff0c;…

前端 - 基础 表单标签 - 表单元素 input - (name Value checked maxlength )属性详解

目录 name 属性 Value 属性 Checked 属性 Maxlength 属性 场景问答 # <input> 标签 除了 type 属性外&#xff0c;还有其他常用属性 >>> name 属性 在上一节 我们遇到的 单选按钮 &#xff0c;为什么 本应该 多选一 结果成了 多选多的问题 就…

# 达梦数据库知识点

达梦数据库知识点 测试数据 -- SYSDBA.TABLE_CLASS_TEST definitionCREATE TABLE SYSDBA.TABLE_CLASS_TEST (ID VARCHAR(100) NOT NULL,NAME VARCHAR(100) NULL,CODE VARCHAR(100) NULL,TITLE VARCHAR(100) NULL,CREATETIME TIMESTAMP NULL,COLUMN1 VARCHAR(100) NULL,COLUMN…

利用甘特图实现精细化项目管控

在项目管理中,通过精细化管控,项目经理能够有效规划、监督和协调各项任务,从而最大限度控制风险,优化资源配置,并确保按时、按质、按量完成项目目标。而在众多项目管理工具中,甘特图无疑是实现精细化项目管控的利器。zz-plan 是一个非常好用的在线甘特图制作工具&#xff0c;一…

Day78:服务攻防-数据库安全RedisCouchDBH2database未授权访问CVE漏洞

目录 前置知识 数据库应用-Redis-未授权访问&CVE漏洞 未授权访问&#xff1a;CNVD-2015-07557 未授权访问-CNVD-2019-21763 未授权访问-沙箱绕过RCE-CVE-2022-0543 数据库应用-Couchdb-未授权越权&CVE漏洞 Couchdb 垂直权限绕过&#xff08;CVE-2017-12635&…

【操作系统】想要更好的学习计算机,操作系统的知识必不可少!!!

操作系统的概念 导言一、日常生活中的操作系统二、计算机系统层次结构三、操作系统的定义3.1 控制和管理计算机资源3.2 组织、调度计算机的工作与资源的分配3.3 给用户和其他软件提供方便接口与环境3.4 总结 四、操作系统的目标和功能4.1 作为管理者4.1.1 处理机管理4.1.2 存储…

yolov5目标检测可视化界面pyside6源码(无登录版)

一、软件简介&#xff1a; 这是基于yolov5-7.0目标检测实现的的可视化目标检测源码 本套项目没有用户登录的功能&#xff0c;如需用户登录版&#xff0c;看另一篇文章&#xff1a;yolov5pyside6登录用户管理目标检测可视化源码_yolov5用户登入功能-CSDN博客 ①程序中图片和图标…

稳定性生产总结

本期我们来谈下稳定性生产这个话题&#xff0c;稳定性建设目标有两个&#xff1a;降发生、降影响&#xff0c; 在降发生中的措施是做到三点&#xff1a;系统高可用、 高性能、 高质量&#xff0c;三高问题确实是一个很热的话题&#xff0c;里面涉及很多点。 在降影响中要做到…

Windows系统搭建TortoiseSVN客户端并实现无公网IP访问内网服务端

文章目录 前言1. TortoiseSVN 客户端下载安装2. 创建检出文件夹3. 创建与提交文件4. 公网访问测试 前言 TortoiseSVN是一个开源的版本控制系统&#xff0c;它与Apache Subversion&#xff08;SVN&#xff09;集成在一起&#xff0c;提供了一个用户友好的界面&#xff0c;方便用…

Wheel Controller 3D

Wheel Controller 3D是Unity内置WheelCollider的完整替代品。它允许更真实的车辆行为、完全定制和3D地面检测。 Wheel Controller 3D是Unity内置WheelCollider的完整替代品。它允许更真实的车辆行为、完全定制和3D地面检测。 如果您正在寻找包含Wheel Controller 3D的完整车辆物…

路径规划——搜索算法详解(六):LPA*算法详解与Matlab代码

上文讲解了D*算法&#xff0c;D*算法为在动态环境下进行路径规划的场景提出了可行的解决方案&#xff0c;本文将继续介绍另外一种动态规划路径的方法——Lifelong Planning A*&#xff08;LPA*&#xff09;算法。 该算法可以看作是A*的增量版本&#xff0c;是一种在固定起始点…

idea开发 java web 酒店推荐系统bootstrap框架开发协同过滤算法web结构java编程计算机网页

一、源码特点 java 酒店推荐推荐系统是一套完善的完整信息系统&#xff0c;结合java web开发和bootstrap UI框架完成本系统 采用协同过滤算法进行推荐 &#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式…