Qt样式(qss)使用小结(软件换肤,比如暗黑模式)

news/2025/3/23 23:55:20/

1.背景:

Qt style sheet(qss)跟前端技术一样,就是为了美化界面。关键是,太好用了。之前还为此写过一篇博客。

Qt样式(qss)的语法定义获得途径,可查资料,可自动生成_大橘的博客-CSDN博客_qt 获取段落的样式

其中主要是记录如何获取手册细节。

现在很多软件都有换肤功能,比如暗黑模式。有了qss就简单太多了。学过前端的朋友一看就会。跟css大同小异。

2.使用:

Style Sheet最主要就是生效范围问题,按照面向对象编程的思维,可以认为它像继承。按照平面设计的思维,可以认为跟画画一样,先画轮廓,再勾细节。

在一个项目中,qss可以统一定义一份,在主窗体加载构造的时候,执行setStyleSheet一下,在这个窗体内部就会全局生效,实现快速换肤。

具体用法手册和网络中有太多,不用赘述。就拿最近我写的qss为例记录一下。

/*background*/
*,QTabBar::tab{background-color:rgb(30, 30, 30);color:rgb(0, 255, 0);}/*disabled*/
*:disabled{color:rgb(200, 200, 200);}/*selected*/
QTabBar::tab:selected,QTableView::item:selected{background-color:rgb(0, 80, 0);}/*hover*/
QComboBox,QDateTimeEdit:hover,QTabBar::tab:hover,QTableView::item:hover,QToolButton:hover,QMenuBar::item:selected,QMenu::item:selected,QPushButton:hover,QLineEdit:hover{background-color:rgb(0, 150, 0);}/*border*/
QTabWidget:pane,QLabel,QMenuBar::item{border: none;}
QComboBox,QDateTimeEdit,QGroupBox,QLineEdit,QTextEdit,QListView,QListView,QTextBrowser,QTableView,QTableView::item{border: 1px solid green;}
QComboBox,QDateTimeEdit,QGroupBox,QLineEdit,QTextEdit,QListView,QListView,QTextBrowser,QTableView{border-radius: 6px;}/*QPushButton*/
QPushButton{background-color:rgb(0, 100, 0);}
QPushButton:pressed{background-color:rgb(0, 100, 0);}/*QScrollBar*/
QScrollBar::handle{background-color:rgb(0, 100, 0);}
QScrollBar::add-page,QScrollBar::sub-page{background-color:rgb(50, 50, 50);}/*QToolTip*/
QToolTip{color:black;}/*QGroupBox*/
QGroupBox{padding-top: 12px;}/*QTableView*/
QTableCornerButton::section,QHeaderView::section,QTableView::item{background-color:rgb(30, 30, 30);border: 1px solid green;}

上面的qss,我先定义了最常用的几个特征:背景、字体、disable、选中、鼠标停留、边框,然后定义了针对每一类控件的特征:按钮、滚动条、提示框、组合框、表格。

先定义常用特征,就好像定义基类,或者画一下轮廓。

后针对控件描述特征,就好像写子类,或者勾画细节。

其实也可以使用“#”号针对具体的控件对象来定义,就好像类的实例化,或者作画的具体细节。

3.问题:

在使用过程中遇到了几个典型问题,这里需要记录一下。

3.1.按钮QPushButton:

目前我还没研究透。控件一般都继承QWidget类,所以一旦定义了QWidget样式,就会间接影响到按钮。按钮最讨厌就是边框问题,一旦定义了border相关属性,只要是没有拉伸的地方,按钮就会变成自适应文本大小。一般界面中可以人为控制还好,就怕QMessageBox这类,一旦变成自适应,就成了这样:

像右下角那俩按钮的德行,什么玩意?

而我尝试的原则,不要试图样式和界面中的各种属性结合控制,很不好,应该尽量把界面做的“通用”,让它随时可以通过定义qss来改变显示风格。

所以目前我都是尽量规避对按钮边框样式的定义,取而代之的,是利用颜色的变化来做显示效果。 

所以正常情况下,我希望按钮是这样的:

3.2.QTabWidget

这东西让不少人头疼,主要是边框问题。

比如右边和下边这个大白边,网上说需要设置界面中的属性documentModel=true,是可以直接实现,但会造成在最上面多一个小白边。所以放弃!

在我的努力下,通过qss实现:

QTabWidget:pane{border: none;}

 这样就可以了,直接去掉了它所有的边框,其它看着玩就行了。

比如做个颜色试试:

QTabWidget:pane{border: 1px solid blue;}

如果要定义页签部分,则需要这样:

QTabBar::tab{background-color:rgb(30, 30, 30);color:rgb(0, 255, 0);}
QTabBar::tab:selected{background-color:rgb(0, 80, 0);}
QTabBar::tab:hover{background-color:rgb(0, 150, 0);}

 

这里我没有使用更高级的用法。其实上面的页签可以定义为圆边,也可以改变位置到左边、右边、下边。还可以用画笔画成其它形状的。

 3.2.3.表格QTableWidget/QTableView

因为QTableWidget继承于QTableView,所以只需要定义QTableView就行了。也就是说,定义了父类,子类也会继承过来样式并生效的。QListWidget&QListView也是一样道理。

 比如上面用到的有关表格的部分:

/*QTableView*/
QTableView{background-color:rgb(30, 30, 30);color:rgb(0, 255, 0);}
QTableCornerButton::section,QHeaderView::section,QTableView::item{background-color:rgb(30, 30, 30);border: 1px solid green;}
QTableView{border-radius: 6px;}
QTableView,QTableView::item{border: 1px solid green;}
QTableView::item:selected{background-color:rgb(0, 80, 0);}
QTableView::item:hover{background-color:rgb(0, 150, 0);}/*QScrollBar*/
QScrollBar::handle{background-color:rgb(0, 100, 0);}
QScrollBar::add-page,QScrollBar::sub-page{background-color:rgb(50, 50, 50);}

 就实现了上图的效果。

3.2.4.菜单和工具栏QMenuBar/QMenu/QToolButton

QMainWindow上面的菜单实际上是两部分组成的,最上面那一条叫菜单栏QMenuBar,每一个主菜单项是它的item,比如:文件、编辑、帮助等,也就是一级菜单。

按一下一级菜单弹出来的才叫菜单QMenu,而其中每一个项也是它的item,比如文件-退出,编辑-剪切,帮助-关于等。

所以要定义一级菜单需要使用QMenuBar::item,定义子菜单项需要使用QMenu::item。比如我需要让鼠标停留的菜单项高亮,就这样写:

QMenuBar::item:selected,QMenu::item:selected{background-color:rgb(0, 150, 0);}

 3.2.5.与QStyle或QPaint生效优先级

按照前端css的说法,样式优先级比属性高。但是qt当中如果使用了画笔绘制,qss是无法生效的,这是我实验的结果。

我认为,qt有点像c#的wpf,说白了特别像html这些前端脚本技术,默认它是透明的,都是用样式在描述它的特征,如果后期自定义了样式,就以后定义的为准。就好像一个变量,先赋值为1,再赋值为2,显然它等于2。

但是画笔是另外一套体系,直接从本质上赋予它颜色,那就不是样式能解决的了。

也许是我还没找到跟权威的说法。

4.小结

先总结这么多,目前为止,我已经用qss实现了换肤机制。

我感觉qtcreator的界面很可能本身就是这么做出来的,只要能掌握方法,ui可玩性很高。


http://www.ppmy.cn/news/7323.html

相关文章

马上又是新的一年了 “跨年倒计时”送给大家

🏆今日学习目标: 🍀跨年倒计时 ✅创作者:林在闪闪发光 ⏰预计时间:30分钟 🎉个人主页:林在闪闪发光的个人主页 🍁林在闪闪发光的个人社区,欢迎你的加入: 林在闪闪发光的…

《计算机网络》——第三章知识点

第三章思维导图 链路层的信道类型 一对一:点对点信道 —对多:广播信道 链路层要解决的问题 封装成帧 透明传输 差错检测密封,透气性差 封装成帧就是在一段数据的前后部分添加首部和尾部,这样就构成了一个帧。接收端在收到物理层上交的比特流后&#xff…

Microsoft .NET Desktop Runtime (Framework)

Microsoft .NET Desktop Runtime (Framework)   Microsoft.NET Framework或数据库是一种软件技术,包括Microsoft.NET中的几种编程语言。安装每个窗口后所需的工具之一是NETFramework技术。会的。基于这种技术编写的许多软件工具,它们将得到支持。 -是的…

MindSpore模型快速调优攻略笔记分享(上)

• 近年来,深度学习技术在语音识别、自然语言处理、计算机视觉、信息检索等任务上取得了突破性进展; • 深度学习模型的复杂度与规模日益扩张,导致模型的调试调优成为了困扰算法工程师的一大难题; • MindSpore是由华为自研的深度学习框架,…

“设计”小哥转行5G网络优化工程师!从零开始,三个月实现逆风翻盘~

5G网络优化,一个陌生的领域,对于一个毫无经验的小白来说,选择转行必定是需要勇气和决心的。好在,在决定选择5G网络优化的这一段时间里,老师给予了我最大的帮助和支持,包括从授课,到练习&#xf…

nginx常用配置

目录 1、全局块 2、events块 3、http块 3.1、http基本配置 3.2、http反向代理基本配置 3.3、http反向代理服务器和负载均衡 3.4、http_gzip配置 3.5、server相关配置 3.5.1、server基础配置 3.5.2、ssl配置 3.5.3、location配置 4、一个简单的nginx配置实例 1、全局…

Lua基本数据类型

Lua官网文档入口 http://www.lua.org/ document --> manual 一、基本数据类型 lua 中有八种基本数据型,分别是: nil,boolean,number,string,function,userdata,thread 和 tab…

Git分支操作

实操记录 假定非管理人员操作: 直推: 新建特性分支cbry: 刷新分支: checkout切换: 本地文件查看: 再merge: 就此,master的代码就合并到特性分支cbry: 新增内容&#xff…