当前位置: 首页 > article >正文

学习Qss--Qss的特性

一、层叠性

qss的语法来源于css,而css的全称是Cascading StyleSheet,翻译过来叫做层叠样式表,也叫级联样式表。层叠性是css处理冲突的一种能力,只有在多个选择器匹配到同一个控件时才会发生层叠性,例如:

btn1->setStyleSheet("QPushButton{ color: blue; }");
btn1->setStyleSheet(".QPushButton{ color: green; }");

这两个选择器匹配到了同一个按钮,结果是后面的样式覆盖了前面的,这就是层叠现象。

二、继承性(Qt-Version>=5.7)

在典型的CSS中,如果一个标签的字体和颜色没有显示设置,它们会自动从其父亲获得。当使用Qt样式表时,控件不会从其父亲继承字体和颜色的设置(请注意,父亲和父类、孩子和子类都是不同的概念,不要搞混),例如,考虑一个QGroupBox内有一个QPushButton:

qApp->setStyleSheet("QGroupBox{ color: red; }");

QPushButton没有任何显示的color设置。因此,它会获得系统的颜色而不是从父亲继承color的值。如果我们要设置QGroupBox及其所有孩子的color,我们可以这样写:

qApp->setStyleSheet("QGroupBox,QGroupBox *{ color: red; }");

注意QGrouBox和*之间的空格。

与此相反,使用QWidget::setFont()可以设置字体包括孩子的字体,使用QWidget::setPalette()可以设置调色板包括孩子的调色板。

如果想要字体和调色板被孩子继承,可以给QApplication设置​​​Qt::AA_UseStyleSheetPropagationInWidgetStyles(Qt5.7 加入)属性​​,例如:

QCoreApplication::setAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles,true);

Qt学习基地(免费报名学习):C/C++项目实战/Qt5/C语言/c++/数据库/OpenCV/MFC/QT项目-学习视频教程-腾讯课堂

三、优先级

当一个控件被多个选择器选中并且设置了相同的属性(值不同)时,不能仅仅根据设置样式语句出现的先后顺序进行层叠,那么控件的样式如果确定,于是引出了选择器的优先级问题。一般通过下面两步进行选择器优先级的判定。

第一步:设置方式所产生的优先级问题

在CSS中,有如下层叠优先级规则:

内联样式 > 内部样式 > 外部样式 >

而在Qss中,这个规则表现为:

给控件直接设置的样式 >

就是说,调用控件的setStyleSheet设置的样式的优先级永远高于给QApplication设置的样式,即使QApplication中的选择器优先级更高。

第二步:样式表本身的优先级问题

当设置方式相同,且几个样式规则为同一个控件的同一个属性指定不同的值时,就产生了冲突。此时,如何层叠就要由选择器的优先级来确定。

一般而言,选择器越特殊,它的优先级越高。也就是选择器指向的越准确,它的优先级就越高。

优先级判断的三种方式

间接选中

间接选中就是指继承,也就是在Qt5.7及以上版本,程序中给QApplication对象设置了​​​Qt::AA_UseStyleSheetPropagationInWidgetStyles​​​属性时,才会有间接选中。

如果是间接选中,那么最终的样式就是离目标最近的那个,这里的近指的是两个控件的父子关系。例如一个QPushButton对象被布局在QGroupBox中,而QGroupBox又被布局在QWidget中,此时如果给QGroupBox和QWidget都设置了color属性的颜色,那么无论设置顺序如何,QPushButton的前景色总是表现为QGroupBox设置的颜色,因为QGroupBox显然是离QPushButton最近的那一个。

相同选择器(直接选中)

如果都是直接选中,并且都是同类型的选择器,那么写在后面的样式会覆盖掉前面的样式,例如:

btn1->setStyleSheet("QPushButton{ color: green; }");
btn1->setStyleSheet("QPushButton{ color: blue; }");

不同选择器(直接选中)

如果都是直接选中,并且不是相同类型的选择器,那么就会按照选择器的优先级来层叠。

具体的优先级如下:

ID > 类 > 类型 > 通配符 > 继承 >

优先级权重

当多个选择器混合在一起使用时,我们可以通过计算权重来判断谁的优先级最高,从而确定控件的样式。

注意点:只有选择器时直接选中控件是才需要计算权重,否则直接选择器高于一切间接选中的选择器。

优先级权重的计算方式:

计算选择器中的id选择器数量[=a]

计算选择器中类选择器的数量+属性选择器的数量[=b]

计算选择器中类型选择器的数量[=c]

忽略子控件选择器

串联这三个数字a-b-c就得到优先级权重,数字越大优先级越高。

Qt官方关于冲突解决的说明

当几个样式规则为同一个属性指定不同的值时,就产生了冲突。请考虑下面的样式表:

QPushButton#okButton { color: gray; }
QPushButton { color: red; }

两条规则都匹配名为okButton的QPushButton实例并且冲突于颜色属性。为了解决冲突,我们必须考虑到选择器的特殊性。在上面的例子中,QPushButton#okButton被视为比QPushButton更特殊,因为它(通常)指向一个单一的对象,而不是QPushButton的所有实例。

相似的,指定了伪状态的选择器比没有指定伪状态的更特殊。从而,下面的样式表指明了当鼠标悬浮到QPushButton上方时其字体颜色应该为白色,而其余情况为红色:

QPushButton:hover { color: white; }
QPushButton { color:red; }

接下来看一个很有意思的:

QPushButton:hover { color: white; }
QPushButton:enabled { color: red; }

两个选择器都有相同的特殊性,所以当鼠标悬浮在一个enabled的按钮上时,第二条规则优先。如果在这种情况下我们想要文字变为白色,我们可以像下面那样重新排布一下样式规则:

QPushButton:enabled { color: red; }
QPushButton:hover { color: white; }

另外,我们可以使第一条规则更特殊一些:

QPushButton:hover:enabled { color: white; }
QPushButton:enabled { color: red; }

相似的问题出现在相互配合的类型选择器上。考虑以下情况:

QPushButton { color: red; }
QAbstractButton { color: gary; }

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QT嵌入式开发,Quick模块等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓ 

两条规则都应用于QPushButton的实例(因为QPushButton继承于QAbstractButton)并且冲突于color属性。因为QPushButton继承于QAbstractButton,这让人不禁想到QPushButton比QAbstractButton更特殊。然而,对于样式表的运算,所有的类型选择器都具有同等的特殊性,并且出现在更后面的规则优先级更高。换句话说,QAbstractButton的color会被设置成灰色,包括QPushButton。如果我们确实想要QPushButton字体颜色设置为红色,我们总是可以使用重新排列样式表规则顺序的方式实现。

为确定规则的特殊性,Qt样式表跟随CSS2规范

一个选择器的特殊性由下面的方式计算:

计算选择器中ID属性的数量[=a]

计算选择器中其它属性和伪类的数量[=b]

计算选择器中元素名字的数量[=c]

忽略伪元素[如:subcontrol]

串联这三个数字a-b-c(在一个大基数的数字系统)就得到了特殊性等级。例如:

* {} /*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*/

四、盒模型

4.1、什么是盒模型?

盒模型仅仅是一个形象的比喻,所有的widget都被看做是一个“盒子”,一个盒子包括:外边距,边框,内边距,和实际内容。它们可以看做是有包含关系的矩形,并且这种包含关系是固定不变的。如图所示:

Margin(外边距):与其他盒子之间的距离;

Border(边框):外边距与内边距之间的区域。边框有自己的颜色不会受到盒子的背景颜色影响;

Padding(内边距):内容和边框之间的区域。会受到背景颜色的影响;

Content(内容):盒子的内容,显示文本,图像或其他控件。

除了内容外,其他三个部分均不能单独设置颜色,智能设置其宽度,并且使以像素为单位。

4.2、盒模型中的宽度与高度

在属性中将要学到width,height两个属性,设置的均是盒子的内容的宽高,而我们在C++代码中的窗口的width与height指的是整个盒子的宽度与高度,这一点非常重要。

整个盒子的宽度应该等于:

左外边距+左边框+左内边距+内容宽度+右内边距+右边框+右外边距

同理,整个盒子的高度也是上下外边距,内边距和内容高度的和。

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QT嵌入式开发,Quick模块等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

http://www.lryc.cn/news/2416970.html

相关文章:

  • 高并发下System.currentTimeMillis()性能问题及优化方案
  • 串口(SerialPort)的使用
  • 常用正交表(正交法编写测试用例)
  • Redis——持久化之RDB
  • rhapsody软件_Rhapsody集成引擎之日志篇(一)
  • 撞库及其危害性
  • log4net的使用步骤
  • 2的n次方对照表
  • 【Android 四大组件之Service】一文吃透Service 服务
  • Linux 文件系统挂载 INITRAMFS 与 INITRD
  • PreparedStatement 用法
  • Nginx-基本安装
  • Windows Vista 系统中的用户帐户控制和UAC远程限制 设置
  • 总线概述及常见总线
  • 基于JAVAWeb+Tomcat+Mysql开发的微电影网站
  • Java 常用代码汇总-附源码
  • C语言之文件读写——fscanf(),fprintf()详解
  • mailbox机制实例介绍(一)
  • 线性代数——余子式
  • HCIP------ 网络类型 PPP协议和HDCL协议
  • TrueCrypt原理与系统开发
  • 数据增强 - Cutout、Random Erasing、Mixup、Cutmix
  • 探索 `mpvue-vant`: 微信小程序开发的新利器
  • mint-ui使用
  • JqGrid 各个属性、方法使用说明
  • 快速上手 Rook,入门云原生存储编排
  • xxxxxxxxxxxxxxxxxxxxx已转行
  • ROV简易组装说明
  • 还在为没有项目做发愁?这几个神级开源网站,都是FPGA/IC项目
  • segment fault异常及常见定位手段