1. Qt样式表概述
对Qt样式表应用毫无基础的可以先了解下Qt官方对样式表的说明:https://doc.qt.io/qt-5/stylesheet.html
简单来说就是给Qt的控件"化妆", 同样的控件可以通过改变样式表的设置表现出不同的效果,这些效果主要包括颜色、字体、线条样式、线条粗细等各种各样的属性.
2. QSS和CSS的区别
做过Web开发的童鞋应该都了解层叠样式表(CSS),主要是用来修饰网页dom的网页元素;而Qt开发使用的QSS也是从CSS发展过来的;主要的语法基本相同或类似,区别在于QSS相比CSS要弱很多,选择器类型要少一些,可用的属性也相对少一些,而且并非所有的属性都能在所有的Qt控件上得到支持
3. Qt样式表的简单应用
写一个程序在主窗口上放上一个测试PushButton,显示出来如图所示:
这个没啥难度吧,代码就不粘贴了;我们现在对最上层的QWidget设置样式表,改变一下背景色,修改为蓝色. Qt设置样式表通常有以下三种方式:
1> Qt Designer上直接右键控件选择"改变样式表选项", 添加样式表
2> 代码里面使用控件对应的SetStyleSheet方法设置样式表
3> 将样式表样式写到单独的.qss文件中,加载.qss文件改变样式
详细的案例可以看Blog : https://blog.csdn.net/m0_60440984/article/details/125007767
我们这里采用第一种方式改变样式表内容,代码如下:
background-color: rgb(0, 255, 255);
改变样式表后的界面如下:
4. Qt样式表语法
对样式表学习感兴趣的同学可以详细学习css语法:https://www.w3school.com.cn/css/index.asp
内容很多,如果不是专业UI开发其实只需要了解一些简单的内容即可。这里不过多介绍,重点聊一下QSS支持的选择器类型;至于支持的控件和属性,开发中有涉及再自行查阅即可。
所谓选择器就是一个界面比如使用了一个QSS样式表,样式表中可以使用不同类型的选择器来选择界面上的不同控件,比如在CSS样式表中使用类型选择器代码如下:
QPushButton {background: gray;
}
样式表代码的意思为选择了界面上所有的PushButton控件,并将这些按钮的背景色设置为灰色;QSS主要支持以下9类选择器
1> 通用选择器* : *作为选择器,作用于所有的Widget
2> 类型选择器 : 类名作为选择器,作用于它自己和它的所有子类
3> 类选择器 : .类名或.class的属性值作为选择器,作用于它自己,它的子类不受影响
4> ID选择器 :#对象名,作为选择器,仅仅作用于该对象
5> 属性选择器 : 选择器[属性=“值”] 作为选择器,这个属性可用通过 object->property(propertyName) 访问的,Qt 里称为 Dynamic Properties,示例代码
app.setStyleSheet(".QWidget { background: gray; }""QPushButton[level='dangerous'] { background: magenta; }");openButton->setProperty("level", "dangerous");
closeButton->setProperty("level", "dangerous");
6> 包含选择器 : 通常使用如下格式作为包含选择器:类名 类名,选择器之间用空格隔开,作用于widget中的子widget,子widget中的子widget,依次类推, 示例代码
QFrame {background: gray;
}/* 设置 QFrame 中的 QPushButton 的 QSS */
QFrame QPushButton {border: 2px solid magenta;border-radius: 10px;background: white;padding: 2px 15px;
}
如上代码,QFrame中的QPushButton的样式会生效,QFrame外的QPushButton不会生效
7> 子元素选择器 : 通常使用如下格式作为包含选择器:类名 类名,选择器之间用>隔开,作用于widget的直接子widget,示例代码
QFrame {background: gray;
}QFrame > QPushButton {border: 2px solid magenta;border-radius: 10px;background: white;padding: 2px 15px;
}
与包含选择器的区别在于只作用于直接子对象,间接子对象不受影响;如上代码,作用于widget的直接子widget,直接子widget的子widget不生效
8> 伪类选择器 : 选择器:状态 作为选择器,支持!操作符,表示非,示例代码
QPushButton:hover { color: white }
QCheckBox:checked { color: white }
QCheckBox:!checked { color: red }
通过QSS设置按钮的悬浮、按下等效果时,一般选用这种方式进行设置。
伪类选择器支持链式规则,即选择器:状态1:状态2:状态3,状态之间使用逻辑与,同时满足条件样式才生效,示例代码
QCheckBox:hover:checked { color: white }
Qt样式表里面常用的伪类选择器有以下几种
- :disabled Widget 被禁用时
- :enabled Widget 可使用时
- :focus Widget 得到输入焦点
- :hover 鼠标放到 Widget 上
- :pressed 鼠标按下时
- :checked 被选中时
- :unchecked 未选中时
- :has-children Item 有子 item,例如 QTreeView 的 item 有子 item 时
- :has-siblings Item 有 兄弟,例如 QTreeView 的 item 有兄弟 item 时
- :open 打开或展开状态,例如 QTreeView 的 item 展开,QPushButton 的菜单弹出时
- :closed 关闭或者非展开状态
- :on Widget 状态是可切换的(toggle), 在 on 状态
- :off Widget 状态是可切换的(toggle), 在 off 状态
9> SubControl选择器 : 这个是Qt中独有的选择器,css中没有;有些 widget 是由多个部分组合成的,可以使用 选择器::subcontrol 来设置 subcontrol 的样式(不常用,了解即可)
参考Blog : https://blog.csdn.net/u011832219/article/details/128199636
5. Qt样式表的继承
众所周知,Qt的对象管理一般是使用对象树的方式进行管理;每个控件一般都有其父类.Qt的样式表设置可以继承,即对父类设置的样式表,对其子类仍然有效(除非子类对父类的样式表进行改写,则以子类改写的样式为准);
例如第3章节举的栗子,可以看到我们只是修改了顶层的QWidget的背景色,实际上测试按钮的背景色也发生了改变;这个就是由于测试按钮控件的父类是顶层QWidget,顶层QWidget设置的样式表样式被其继承产生的效果.
这里需要注意一下有两种情况子类不会继承父类的样式表效果:
1> 子类对父类设置的样式进行了重置,例如第3章节栗子中,测试按钮重新设置背景色为红色,那么显示就是父类是蓝色,按钮是红色
2> 父类设置样式表的时候以类选择器、对象选择器进行设置
3> 父类支持的属性,子类不支持