QSS使用总结

QSS使用总结:

1. 什么是QSS
QSS:全称Qt Style sheet即Qt样式表,他是Qt提供的一种用来自定义控件外观的机制。
QSS大量参考了CSS的内容,只不过QSS的功能比CSS要弱很多,体现在选择器更少,可以使用的属性也更少,
并且并不是所有的属性都可以在Qt的所有控件上。

2. QSS的使用
1 全局QSS文件方式
  一般将项目中所有控件的样式写入一个文件中,然后在程序启动后加载文件然后设置全局的样式
 
int main(int argc, char* argv[])
{
    ...
    QFile file(":/qss/default.qss");
    file.open(QFile::ReadOnly);
    QTextStream filetext(&file);
    QString styleSheet = filetext.readAll();
    qApp->setStyleSheet(styleSheet);
    ...

2 在程序中为某个具体的控制设置样式
ui->okBtn->setStyleSheet("font-size:30px");

--->当用户在程序中设置了控件的qss样式,则会覆盖全局的样式

3. QSS的语法规则
QSS的规则几乎和CSS相同,一条QSS样式由两部分组成,一部分为选择器 指定了设置样式的控件,另一部分为指定的属性的值,表示哪些属性会收到影响QPushButton{ color: #FF0000}。
QPushButton表示选择器,指定了所有的QPushButton以及其子类会收到影响,注意凡是继承QPushButton的类都会受到影响,这点与CSS不同,因为CSS没有类/子类的概念仅为标签。
而后的{ color: #FF0000}则是规则的定义,表明指定前景色为红色,该样式的意义为设置QPushButton类以及子类的所有实例的前景色设置为红色

如果MyButton继承自QPushButton,么上面的规则也会应用到所有MyButton控件上,但是如果规则是如下的:
MyButton{color:#FF0000} 
则只会对MyButton的实例应用红色的前景颜色,而对QPushButton的实例没有应用。

4. `
通配选择器:*; 匹配所有的控件
类型选择器:QPushButton; 匹配所有的QPushButton和其子类的实例
属性选择器:QPushButton[flat="false"]; 匹配所有flat属性为false的QPushButton实例,也可以使用自定义的属性
类选择器: .QPushButton; 匹配所有的QPushButton的实例,但是不匹配其子类。这与CSS中的选择器不一样,其前面有个点号
ID选择器: #myButton; 匹配所有ID为myButton的控件实例,这里的ID指的是objectName指定的值
后代选择器: QDialog QPushButton; 所有QDialog容器下面的QPushButton, 不管是直接的还是间接的
子选择器:QDialog > QPushButton; 所有的QDialog容器下面的QPushButton,其中要求QPushButton的直接父类控件使QDialog
--->另外上面的所有的这些选择器可以联合使用,并且支持一次设置多个选择器类型,用逗号隔开,这点和CSS一样
例如:frameCut,#frameInterrupt,#frameJoin 表示所有这些id使用一个规则。#mytable QPushButton 表示选择所有id为mytable的容器下面的QPushButton实例。

5. QSS子控件
QSS的子控件实际上也是选择器的一种,因为这种选择器与CSS有一些不同,所有单独列出来。QSS的子控件选择器是应用在一些复杂控件上的,典型的例如QComboBox,
该控件的外观包含几个部分,一般情况下有一个矩形的外边框,右边有一个向下的箭头用于点击之后会有弹出下拉列表。
例如:QComboBox::drop-down{image:url(":/iamges/dropdown.png")}
上面的样式指定所有的QComboBox的下拉框箭头的图片为自定义图片dropdown.png
::dropdown子控件选择器也可以与上面提到的选择器一起联合使用。
QComboBox#myComboBox::drop-down{image:url(":/iamges/dropdown.png")}
指定id名为myComboBox的QComboBox控件的下拉箭头的自动以图片,要注意的是子控件选择器实际上是选择复合控件中的一部分,也就是说对复合控件中的一部分应用样式,
例如QComboBox的下拉箭头指定图片而不是为QComboBox指定图片

QSS为很多复杂的复合控件提供了子控件的定义,以方便对这些复合控件的各个部分进行样式设置。限于篇幅,本文也不能将这些可用的子控件都列出来,在安装QtCreator之后自带的帮助中就有很详细的描述。

https://blog.csdn.net/Staranywhere/article/details/106652678

6. QSS伪状态
QSS的伪状态选择器实际上与CSS中的类似,是以冒号开头的一个选择表达式。例如:hover表示当鼠标经过时的状态,他限制了当控件在某一种状态下的时候才能应用QSS规则。伪状态只能描述一个控件的状态,或者是一个复合控件的子控件的状态,所以该伪状态选择器智能放在选择器的最后面
例如:QComboBox:hover{background-color:red;} 该规则表示当鼠标经过QComboBox上面时,其背景色指定为红色,该伪状态:hover描述的是QComboBox的状态
伪状态除了可以描述选择器的控件以外,还可以描述子控件选择器所选择的复合控件中的子控件的状态。
例如: QComboBox::drop-down:hover{background-color:red;} 该规则表示鼠标经过QComboBox的下拉框箭头的时候,该下拉框的背景颜色变成红色。
几个伪状态可以一起使用, 例如:QCheckBox:hover:checked{color: red} 指定一个当鼠标经过一个选中的QCheckBox的时候,设置其文字的前景颜色为红色

QSS提供了很多的伪状态,一些伪状态只能用在特定的控件上,具体有哪些伪状态,在Qt的帮助里面有详细的列表,限于篇幅这里也不列出了。

https://blog.csdn.net/Staranywhere/article/details/106967756

7. QSS级联与冲突
QSS中的级联包含以下几个方面
1 当在同一个控件上应用两个不同的规则, 那么应该应用哪一个规则的问题,也就是如何解决这种冲突
2 在一个容器控件上设置的QSS规则会对容器里面的控件产生效果(这要取决于容器控件上设置的QSS规则时什么样的规则, 如果其规则仅仅针对容器控件本身则该子控件无影响,如果该QSS规则里面还有对子控件的设置,则自然会对子控件产生效果)。
级联问题是解决当一个控件被层层父容器包裹,并且在每一层的父容器都有对该控件的样式设置的时候,该控件的最终效果是合并这些父容器上的QSS效果

冲突问题:
QPushButton#okButton{color: gray}
QPushButton{color: red}
这两条规则都会应用到名为obButton的按钮上,但是他们为同一个属性设置了不同的颜色,这会有冲突,那么要解决这样的冲突就必须考虑到选择器的特异性(具体性),显然QPushButton#okButton仅仅针对对象名为okButton的控件有效果,而QPushButton却对所有的QPushButton的实例或者是其子类的实例有效果,显然QPushButton#okButton选择器更加特殊,也就是更具有特异性。所以最终okButton前景色被应用为灰色。如果两条规则的特异性一样,那么就选择声明靠后的那一条。
--->另外如果一个选择器应用了伪状态,而另一个没有,那么应用伪状态的选择器更加特殊。
例如:
    QPushButton: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的前景颜色被应用为红色,而不是灰色。

有没有一个办法来确定两条QSS规则的特异性大小呢,其实QSS使用的特异性的计算方法与CSS是一样的,详细可以参考CSS2的文档规范,这里还是简要的说明一下,特异性这个东西在CSS中一般被称为权重,权重越大的越优先使用,CSS的计算规则如下:
A 计算一条规则中id选择器的个数,假设存放在变量a中
B 计算一条规则中类选择器和属性选择器的个数,粉放在变量b中
C 计算一条规则中的类型选择器的个数,存放在变量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 */
上面的计算规则是CSS的计算规则,同样可以应用的QSS上。

关于级联:
QSS可以设置在QApplication上,也可以设置在一个部件的容器部件上,也可以设置在子孙控件上,一个部件最终使用的样式是合并了他的所有父容器,祖父容器等上面设置的所有样式的结果,这些设置会进行叠加。 如果发生冲突,则选择部件本身设置的样式效果
--->QSS中似乎为父容器控件本身设置了样式,并不会被子控件继承。
例如如果QFrame中有一个QPushButton控件,则语句 ui->frame->setStyleSheet{"Frame{color: red; border: 1px solid red}"} 仅仅为QFrame设置样式并不会应用到其里面的QPushButton上。 如果下面的语句就可以:
ui->frame->setStyleSheet("QPushButton{ color: red; border:1px solid red }");
ui->frame->setStyleSheet("*{ color: red; border:1px solid red }");

8 QSS实际应用中要注意的地方
在使用QSS的时候遇到过一些坑,看似简单,但是如果不知道的话,还是很折磨人的:
<1>使用QSS设置边框无效,例如:
border:1px solid red; //Ok
border:solid 1px red; //Error
border:red 1px solid; //Error
border:red solid 1px; //Error
设置边框颜色和像素的时候,必须是第一种顺序,而CSS中是无所谓的,至于原因,我也不清楚,就是这么坑人。

<2> QSS设置宽高无效:
在QSS中设置宽高必须要使用 min-width和min-height,max-width,max-height来设置,用width和height设置是没有任何效果的。

<3>QComboBox的样式设置的问题:
QcomboBox是一个复杂的控件,QComboBox由3部分组成,一个是QComboBox的外框,里面有一个下拉按钮,这个按钮可以通过QComboBox::drop-down 来控制其位置,将其定义到QComboBox的左边而不一定是右边。另外在这个下拉按钮上面一般会有一个向下的箭头,这个箭头图像也是可以定制的,通过QComboBox::down-arrow来指定箭头的图像。

如果要控制QComboBox的弹出下拉列表的样式需要通过:
QComboBox QAbstractItemView {
  //设置当点击下拉按钮之后弹出的下拉列表的样式,要注意的是这里的样式
  //仅仅只能设置弹出的整个下拉列表范围的矩形的样式,不能设置下拉列表
  //中的每一个下拉项的样式,例如不能设置每一个下拉项高度
}
QcomboBox{
  //设置未弹出下拉列表的样式
}
 
QComboBox QAbstractItemView::item {
//设置弹出下拉列表中的每一个下拉项的样式,这里的样式要想生效,必须先
//对QcomboBox做下面的设置
//QStyledItemDelegate* itemDelegate = new QStyledItemDelegate();
//combox->setItemDelegate(itemDelegate);   
}

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值