通用选择器又叫通配符选择器;
格式:
* {
attribute: value; }
通用选择器用(*)来表示,它表示匹配程序中所有的widget。
注意点:由于通用选择器会匹配所有的widgets,效率较低,因此应该尽量减少或者不用
一般用法:通用选择器一般用来给应用程序设置统一的字体,例如:
* {
font: normal 20px “微软雅黑”; }
这条语句表示将程序中所有widget的字体大小都设置为20px大小,字体采用微软雅黑。
格式:
className {
attribute: value; }
类名即Widget类名,由QObject::metaObject()::className
获取,类型选择器匹配所有该类以及该类的派生类的对象,例如:
QPushButton
{
color: blue;
}
这条语句表示,程序中所有的QPushButton类和它的派生类的对象,它们的前景色(即文字颜色)被设置为蓝色。
注意点:Qt样式表使用widget的QObject::className()来决定何时应用类型选择器。当自定义控件在命令空间之中(或它是一个嵌套类),QObject::className()会返回(::),这与子控件选择器相冲突,为了解决这个问题,当为命名空间中widget使用类型选择器时,我们必须将"::
“替换成”--
",例如:
namespace ns
{
class MyPushButton : public QPushButton
{
//...
}
}
//...
qApp->setStyleSheet("ns--MyPushButton {
background: yellow; }");
一般用法:类型选择器会匹配所有该类以及该类的派生类的对象,所以我们在程序中,有时为了统一一些具有相似性的控件的样式,可以使用类型选择器,如,我们想要为QSpinBox,QDoubleSpinBon,QDateTimeEdit,QDateEdit,QDataEdit等这些编辑框的控件设置一些相同的样式,因为它们都是QAbstractSpinBox类的派生类,因此可以如下写:
QAbstractSpinBox
{
min-height: 30px;
max_height: 30px;
border-width: 1px;
rder-style: solid;
order-color: gray;
padding: 0px;
}
格式:
.className {
attribute: value; }
这里的类名与类型选择器中的类名一样,不同的是,类选择器的类名前面有一个(.
),这种选择器只会匹配该类的所有对象,而不会匹配其派生类的对象。例如:
.QPushButton
{
color: blue;
}
一般用法:类选择器提供了一种匹配该类的对象但不会匹配派生类的方法,通常用来特例化拥有派生类的类对象,但不仅限于此。例如在应用程序中,使用QFrame作为容器widget,此时想要对它设置一些样式,但又不想影响它的子类对象(QLable、QAbstractScrollArea等等),那么就可以使用类选择器给所有的QFrame设置相同的样式,例如:
.QFrame
{
padding: 15px 25px;
}
格式:
#ID {
attribute: value; }
这里的ID指的是objectName,每个QObject类及其派生类都有一个属性,“#”+objectName构成了ID选择器,它匹配所有objectName为ID选择器所指定的名称的对象,为其设置样式,例如:
#button_1
{
color: red;
}
注意点:
className#ID {
attribute: value; }
但实际上不加类名也是可以的(加了类名的ID选择器在CSS中被称为交集选择器),在正式开发中,还是建议加上类名,因为这样可以看出这个ID选择器所匹配的对象的类型,有利于提高阅读性。一般用法:ID选择器一般用于比较特殊的控件设置样式,例如在应用程序的某个页面中,需要突出一个重要的按钮,那么此时我们可以给这个按钮设置一个独特的样式用以提醒用户,如:
QPushButton#settings_popup_fileDialog_button
{
min-height: 31px;
min-width: 70px;
border: 1px solid black;
color: #FOFOFO;
min-height: 10px;
border-radius: 3px;
background: qlineargradient(spread: pad, x1:0,y1:0,x2:0,y2:1,stop:0 #454648,stop:1 #7A7A7A);
}
格式:
selector1 selector2 {
attribute: velue; }
这个选择器表示:在选择器1匹配的所有对象中,找到选择器2匹配的所有后代对象,并给它们设置样式。
注意点:
selector1 selector2 ... selectorN { attribute: velue; }
BaseDialog QPushButton
{
min-width: 12px;
min-height: 40px;
max-width: 120px;
max-height: 40px;
font-size: 20px;
padding: 0px;
}
格式:
selector1>selector2 {
attribute: value; }
子元素选择器表示找到指定选择器所匹配的对象中的所有特定直接子元素然后设置属性,即找到选择器1匹配到的对象中的被选择器2匹配到的直接子元素然后设置属性。
注意点:
QGroupBox
中的QPushButton
,QWidget>QPushButoon{ color: red; } ①
QGroupBox>QPushButton{ color: red; } ②
QGroupBox
是QWidget
的派生类,类型选择器QWidget
会选中所有它的派生类对象,这些对象中包括QGroupBox
,因此写法①会将所有的QPushButton
的前景色设置为红色。.QGroupBox>.QCheckBox
{
color: blue;
}
格式:
[attribute=value]{
attribute: value; }
[attribute|=value]{
attribute: value; }
[attribute~=value]{
attribute: value; }
attribute=value
表示匹配有特定属性attribute,并且值为value的所有控件,然后设置样式;
attribute|=value
表示匹配有特定属性attribute,并且值以value开头的所有控件,然后设置样式;
attribute~=value
表示匹配有特定属性attribute,并且值包含value的所有控件,然后设置样式。
注意点:
1、 attribute|=value
表示attribute属性的值以value开头,无论value后面还有没有值,或者value后面是什么,均能匹配到,例如:
[objectName|="button"]
{
color: red;
}
这表示将objectName属性以button开头的所有控件的前景色设置为红色。
2、 attribute~=value
表示attribute属性的值中包含value,这里要注意的是value必须是独立的单词,也就是包含value并且value是被空格隔开的,例如:
[objectName~="button"]
{
color: red;
}
在代码中,设置的objectName的语句为:
btn1->setObjectName("button123");
btn2->setObjectName("abc button 2");
结果只会匹配到btn2所指的对象
3、官方文档的解释:通常情况下,这里的属性指的是,使用Q_PROPERTY宏声明的属性,并且属性类型要受QVariant::toString()支持。
这个选择器类型也可以用来判断动态属性,要了解更多使用自定义动态属性的细节,请参考使用自定义动态属性。
处理使用=,还可以使用~=来判断一个QStringList中是否包含给定的QString。
警告:如果在设置了样式表后,相应的属性值发生率改变(如flat变成了"true"),则有必要重新加载样式表,一个有效的方法是,取消样式表,再重新设置一次,下面的代码是其中的一种方式:
style()->unpolish(this);
style()->polish(this);
一般用法:属性选择器一般不常用,如果要用,可以参照官方文档的方法使用
格式:
selector1,selector2,selector3{
attribute: value; }
并集选择器表示,将每个单独选择器匹配到的控件放在同一结果集中,并给结果集中的每个控件都设置声明语句中的样式。
注意点:
一般用法:主要用于给具有相同属性并且外观相似的控件设置样式,例如:
.QLineEdit,.QComboBox
{
border: 1px solid gray;
background-color: white;
}
格式:
类型选择器::子控件{
属性: 值; }
类选择器::子控件{
属性: 值; }
表示对类型选择器或类选择器指定的所有控件的子控件设置样式;
Qt官方说明:
为了样式化你的复杂widget,很有必要使用widget的subcontrol,比如QComboBox的drop-down部分或者是QSpinBox的上和下箭头。选择器也许会包含subcontrols用于限制widget的subcontrols,例如:
QComboBox::down-arrow
{
image: url(:/res/arrowdown.png);
}
上述规则样式话所有QComboBox的drop-down部分,虽然双冒号(::)让人联想到CSS3的伪元素语法,但是Qt的Sub-Controls跟它是不一样的。
Sub-Control始终相对于另一个元素来定义一个参考元素。这个参考元素可以是一个Widget又或者是另一个Sub-Control。例如,QComboBox的::drop-down默认被放置于QComboBox的Padding rectangle(盒子模型)的右上角。::drop-down默认会被放置于另一个::drop-down Sub-Control的中心。查看可样式化的Widget列表以了解很多使用Sub-Control来样式化Widget和初始化其位置的内容。
源rectangle可以使用subcontrol-origin来改变。举个例子,如果我们想要把drop-down方式于QComboBox的margin rectangle而不是默认的Padding rectangle,我们可以像下面这样指定:
QComboBox
{
margin-right: 20px;
}
QComboBox::drop-down
{
subcontrol-origin: margin;
}
drop-down在Margin rectangle内的排列方式可以由subcontrol-position来改变。
width和height属性可以用来控制Sub-Control的size。需要注意的是,设置了image就隐式的设置了Sub-Control的size了。
相对定位方案(position:relative),允许Sub-Control的位置从它的初始化位置作出偏移。举个例子,当QComboBox的drop-down按钮被pressed时,我们也许想要那个箭头作出位移以显示一种"pressed"的效果,为了达到目标,我们可以像下面那样指定:
QComboBox::down-arrow
{
image: url(down-arrow.png);
}
QComboBox::down-arrow:pressed
{
position: relative;
top: 1px; left: 1px;
}
绝对定位方案(position:absolute),使得Sub-Control的position和size基于其参考元素而改变。
一旦定位,它们将会与widget同等对待并且使用盒子模型来样式化。
查看Sub-Control列表以了解哪些sub-control是被支持的,并且可以查看自定义QPushButton的菜单指示器Sub-Control来了解一个实际的使用例子。
注意:像QComboBox和QScrollBar这样的复杂部件,如果sub-control的一项属性是自定义的,那么其他所有的属性跟sub-control也都应该自定义。
格式:
类型选择器:状态{
属性: 值; }
类选择器:状态{
属性: 值; }
表示对类型选择器或类选择器指定的所有控件设置它在指定状态的样式。
Qt官方说明:
选择器也许会包含基于widget的state的程序限制规则的伪状态。伪状态以冒号(:)作为分隔紧跟着伪选择器。举个例子,下面的规则在鼠标悬浮在QPushButton的上方时生效:
QPushButton:hover {
color: white }
伪状态可以使用感叹号进行取反,下面一条规则在鼠标没有悬浮在QRadioButton上方时生效:
QRadioButton:!hover{
color: red }
伪状态可以链接,在这样的情况下,隐式地包含了逻辑与。举个例子,下面的一条规则在鼠标悬浮到一个已check的QCheckBox上时生效:
QCheckBox:hover:checked {
color: white }
伪转态的取反也可以出现在伪状态链汇总,举个例子,下面的规则在鼠标悬浮到一个没有被press的QPushButton上时生效:
QPushButton:hover:!pressed {
color: blue }
如果有需要,可以使用逗号来表示逻辑或,即并集选择器
QCheckBox:hover,QCheckBox:checked {
color: white }
伪状态可以与sub-control组合使用,举个例子:
QComboBox::drop-down:hover {
image:url(dropdown_bright.png)}
如果在C++的代码中直接调用控件对象的setStyleSheet函数来设置样式,但样式中没有任何选择器,例如下面这样:
btn1->setStyleSheet("color: green;");
即使这种写法可以生效,但它不符合语法规则,因此不推荐使用。
经过测试,这样的语句被忽略的选择器相当于通用选择器或下面例子中的选择器,假如btn1是一个QPushButton对象的指针,那么这条语句等价于:
btn1->setStyleSheet("QPushButton,QPushButton *{ color: green;}");
需要完成一个界面,如下图所示:
这里用户名输入框是一个QComboBox对象,密码输入框是一个QLineEdit对象,它们的父控件是一个QDialog,有这样一个需求:给这两个输入框设置相同的边框属性:1个像素宽的蓝色实线框,为了方便更改风格,我有一个qss文件,将所有样式都写在这个文件里,这时,观察发现,这两个控件都是QDialog的子控件,于是可以用后代选择器或者子元素选择器,如下:
第一种:
QDialog QComboBox,QLineEdit
{
border:1px solid blue;
}
第二种:
QDialog>QComboBox,QLineEdit
{
border:1px solid blue;
}
当写完并运行程序后,发现无论采用哪种写法QComboBox是正常的,但是我的程序界面中,其他所有的QLineEdit的边框都变成了1个像素宽的蓝色实线框,而这并不是我想要的效果。
因此对于上面的现象,我们很容易得出结论:多个选择器组合使用时,它们的结合方向是自左向右,而不是我们认为的自右向左。也就是说,这两个选择器分别被理解为{ QDialog QComboBox },QLineEdit和{ QDialog>QComboBox },QLineEdit。
其实,这应该与CSS的选择器匹配规则是一样的,是为了提高效率的一种做法,具体原因在此不细谈。
正确的写法应该是:
QDialog QComboBox,QDialog QLineEdit
{
border: 1px solid blue;
}
或
QDialog>QComboBox,QDialog>QLineEdit
{
border: 1px solid blue;
}