qt 官方文档
https://doc.qt.io/qt-5/stylesheet-syntax.html
什么是QSS
QSS称为Qt Style Sheets也就是Qt样式表,它是Qt提供的一种用来自定义控件外观的机制。QSS大量参考了CSS的内容,只不过QSS的功能比CSS要弱很多,体现在选择器要少,可以使用的QSS属性也要少,并且并不是所有的属性都可以用在Qt的所有控件上。
QSS的语法规则
QSS的语法规则几乎与CSS相同。一条QSS的样式是由两部分组成的,
1、选择器:指定了哪些控件会受到影响
2、属性的值:表示这些控件的哪些属性会受到影响
QPushButton { color: red }
QSS的选择器类型
另外上面所有的这些选择器可以联合使用,并且支持一次设置多个选择器类型,用逗号隔开,这点与CSS一样,例如#frameCut,#frameInterrupt,#frameJoin 表示所有这些id使用一个规则。#mytable QPushButton 表示选择所有id为mytable的容器下面的QPushButton实例
QSS子控件
QSS的子控件实际上也是选择器的一种,因为这种选择器与CSS有一些不同,所以单独拿出来说,QSS的子控件选择器是应用在一些复合控件上的,典型的例如QComboBox,该控件的外观包含几个部分,一般情况下有一个矩形的外边框,右边有一个向下的箭头用于提示点击之后会有弹出下拉列表。例如:
QComboBox::drop-down { image: url(dropdown.png) }
QSS伪状态
QSS的伪状态选择器实际上与CSS中的类似,是以冒号开头的一个选择表达式,例如:hover表示当鼠标经过时候的状态。他限制了当控件在某一种状态下的时候才能应用QSS规则,伪状态只能描述一个控件的状态,或者是一个复合控件中的子控件的状态,所以该伪状态选择器只能放在选择器的最后面,例如:
QComboBox:hover{background-color:red;}
QSS级联与冲突
冲突问题:
QPushButton#okButton { color: gray }
QPushButton { color: red }
考虑到选择器的特异性,越是特例化的优先级越高,所以okButton的颜色设置成gray
另外如果一个选择器应用了伪状态,而另一个没有,那么应用了伪状态的选择器要更加特殊,例如:
PushButton:hover { color: white }
QPushButton { color: red }
显然QPushButton:hover比单纯的QPushButton更加具有特异性。这两条规则表示当鼠标放在按钮上的时候文字是白色,其他情况下都是红色
如下面两个规则的特异性是一样的,那么应该是如何应用呢:
QPushButton:hover { color: white }
//如果鼠标经过则前景白色
QPushButton:enabled { color: red }
//如果按钮是enabled状态则前景红色
所以默认情况下前景文字是红色的,当鼠标经过的时候并不会变成白色,因为他们的特异性是一样的,所以选择后面的,也就是红色。
调换一下顺序
QPushButton:enabled { color: red }
//如果按钮是enabled状态则前景红色
QPushButton:hover { color: white }
//如果鼠标经过则前景白色
当鼠标经过的时候,就变成白色的了,因为他们的特异性一样,所以选择后面的规则,也就是鼠标经过前景变成白色。
如果把其中的一条的特异性增加,例如:
QPushButton:hover:enabled { color: white }
QPushButton:enabled { color: red }
那么第一条的特异性比第二条大,所以应用第一条的规则。
另外一种特异性发生在类型选择器上:
QPushButton { color: red }
//应用在所有的QPushButton上
QAbstractButton { color: gray }
//应用在所有的QAbstractButton上
而在类的继承结构上,QAbstractButton是QPushButton的父类,显然QPushButton更加具有特异性,所以QPushButton的前景颜色被应用为红色,而不是灰色。
CSS的计算规则如下:
1.计算一条规则中id选择器的个数,=a
2.计算一条规则中类选择器和属性选择器的个数,=b
3.计算一条规则中的类型选择器的个数,=c
4.忽略伪元素,对应QSS中的子控件
* {} /* a=0 b=0 c=0 -> specificity = 0 */
LI {} /* a=0 b=0 c=1 -> specificity = 1 */
UL LI {} /* a=0 b=0 c=2 -> specificity = 2 */
UL OL+LI {} /* a=0 b=0 c=3 -> specificity = 3 */
H1 + *[REL=up] {} /* a=0 b=1 c=1 -> specificity = 11 */
UL OL LI.red {} /* a=0 b=1 c=3 -> specificity = 13 */
LI.red.level {} /* a=0 b=2 c=1 -> specificity = 21 */
#x34y {} /* a=1 b=0 c=0 -> specificity = 100 */
C ++命名空间中使用
下面的类型选择器不会生效,
class MyPushButton : public QPushButton {
// ...
}
// ...
qApp->setStyleSheet("MyPushButton { background: yellow; }");
需要在前面增加命名空间
namespace ns {
class MyPushButton : public QPushButton {
// ...
}
}
// ...
qApp->setStyleSheet("ns--MyPushButton { background: yellow; }");