QSS 语法_qss语法-程序员宅基地

技术标签: qt  ui  QSS 完全手册  开发语言  


1. 基本语法

1.1 样式规则

QSS 由样式规则组成。以下是 3 条规则:
样式规则

1.2 选择器、声明

样式规则 = 选择器+声明

1.3 大小写

QSS 不区分大小写,但类名对象名属性名例外!假设有一个名为 objectName 的 QPushButton:

1.4 多个选择器

可以将多个选择器设置同一个声明,使用逗号,分割:

QPushButton, QLineEdit, QComboBox {
     color: red; }

等价于:

QPushButton {
     color: red; }
QLineEdit {
     color: red; }
QComboBox {
     color: red; }

2. 选择器

QSS 支持 CSS2 中定义的所有选择器。

2.1 通用选择器:*

匹配所有 widget。

2.2 类型选择器:QPushButton

匹配 QPushButton 及其子类。

2.3 属性选择器:QPushButton[flat=“false”]

匹配所有设置了 setFlat(false) 的 QPushButton。

使用该选择器既可以:1. 测试任何支持 QVariant::toString() 的 Qt 属性,还支持特殊的类属性,如类名;2. 还可以测试动态属性。

除了=,也可以使用~=来测试 QStringList 类型的 Qt 属性是否包含给定 QString。

注意:设置 qss 后,如果 Qt 属性值发生了变化,则需要强制重新计算 qss。方法是:重新设置 qss。

2.4 类选择器:.QPushButton

匹配 QPushButton,但不包括子类。等价于 *[class~="QPushButton"]

2.5 ID 选择器:QPushButton#okButton

匹配所有对象名为“okButton”的 QPushButton。

2.6 后代选择器:QDialog QPushButton

匹配作为 QDialog 的后代(直接子代、孙代)的 QPushButton。

2.7 直接子代选择器:QDialog > QPushButton

匹配作为 QDialog 的直接子级(即第一代)的 QPushButton。
在这里插入图片描述


3. 子控件

有些 widget 比较复杂,如 QComboBox 有下拉按钮、QSpinBox 有上下箭头,设置这些 widget 时可以指定子控件。

3.1 一个简单示例

例如:

QComboBox::drop-down {
     image: url(dropdown.png) }

3.2 子控件参考矩形

子控件始终相对于另一个元素定位。例如,QComboBox 的 ::drop-down 默认放置在 QComboBox 的 Padding 矩形的右上角。

使用 subcontrol-origin 更改参考矩形。例如,想将下拉菜单放置在 QComboBox 的 “margin 矩形” 中而不是 “padding 矩形” 中,可以这样设置:

QComboBox {
    
    margin-right: 20px;
}
QComboBox::drop-down {
    
    subcontrol-origin: margin;
}

3.3 子控件对齐方式

使用 subcontrol-position 更改 Margin 矩形中下拉菜单的对齐方式。

3.4 子控件大小

使用 widthheight 可以设置子控件的大小。

注意:如果设置了 image 会默认设置子控件的大小。

3.5 子控件相对位置、绝对位置

使用 position: relative 设置相对定位,允许子控件偏离初始位置。
使用 position: absolute 设置绝对定位,允许子控件相对于参考元素更改位置。

一旦使用了 position,子控件就被视为与 widget 相同,就可以使用盒模型设置。

注意:对于 QComboBox、QScrollBar 等复杂 widget,如果设置了某个属性、某个子控件,那么其他的属性、子控件也要设置。


4. 伪状态

伪状态是指 widget 的不同状态。

伪状态位于选择器的末尾,中间有一个冒号 :。例如,鼠标悬浮按钮时:

QPushButton:hover {
     color: white }

使用感叹号 ! 否定伪状态。例如,鼠标未悬浮按钮时:

QPushButton:!hover {
     color: red }

伪状态可以链接,此时默认隐含逻辑与。例如,鼠标悬停在选中的 QCheckBox 上时:

QCheckBox:hover:checked {
     color: white }

可以使用逗号 , 表示逻辑 OR:

QCheckBox:hover, QCheckBox:checked {
     color: white }

伪状态可以与子控件一起出现。 例如:

QComboBox::drop-down:hover {
     image: url(dropdown_bright.png) }

5. 解决冲突

5.1 产生冲突的原因

如果匹配到同一个 widget 的同一个属性但却设置了不同值,就会产生冲突。例如:

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

两个规则都能匹配名为 okButton 的 QPushButton,但是设置了不同的文本色,这时就需要考虑 选择器的优先级

5.2 解决冲突方法1:更具体的选择器

例如:

  • QPushButton#okButton 比 QPushButton 优先级更高,因为它(通常)指的是单个对象,而不是类的所有实例。
  • 具有伪状态的选择器比不指定伪状态的选择器优先级更高。例如:
QPushButton:hover {
     color: white }
QPushButton {
     color: red }

当鼠标悬停在 QPushButton 上时文本为白色,否则为红色。

这是一个棘手的问题:

5.3 解决冲突方法2:相同优先级的选择器,位于下方的优先级高

一个示例,两个选择器优先级相同,但由于 enable 位于 hover 下方,因此优先级更高:

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

另一个示例:

QPushButton {
     color: red }
QAbstractButton {
     color: gray }

虽然 QPushButton 是 QAbstractButton 的子类,似乎更具体,但对于样式表计算,所有类型选择器都具有相同的特性,并且最后出现的规则优先。因此,所有按钮颜色都设置为灰色,包括 QPushButtons。

5.4 优先级计算

Qt Style Sheet 遵循 CSS2 规范

优先级计算规则:

  1. 计算选择器中 ID 属性的数量 a;
  2. 计算选择器中其他属性和伪类的数量 b;
  3. 计算选择器中元素名的数量 c;
  4. 忽略伪元素,如子控件;
  5. 最后,连接 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 */

6. 级联(Cascading)

widget 的 qss 继承 父widget。如果 widget 设置了自己的 qss,则优先级高于继承的 qss。

例如:

qApp->setStyleSheet("QPushButton { color: white }");
myPushButton->setStyleSheet("* { color: blue }");

最终按钮的文本色为蓝色。

级联是一个很复杂的话题,请参阅 CSS2 Specification
注意:Qt 没有实现 !imporant

7. 继承

7.1 CSS 中的继承

在经典 CSS 中,字体和颜色会自动从父项继承。

7.2 QSS 中的继承

注意:Qt Style Sheet 中的 widget 不会自动从其父部件继承字体和颜色

例如,QGroupBox 中有个 QPushButton。QPushButton 不会自动继承 QGroupBox 的颜色,而是使用系统颜色:

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

如果想为 QGroupBox 及其子对象设置颜色,可以这样写:

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

使用 QWidget::setFont()QWidget::setPalette() 设置字体和调色板会传播到子部件。

如果您希望字体和调色板传播到子小部件,可以设置 Qt::AA_UseStyleSheetPropagationInWidgetStyles 标志,如下所示:

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

当启用该功能时,通过 QSS 设置的字体和调色板变化时,其行为类似于调用 QWidget::setPalette()QWidget::setFont()。如果所调函数能在 C++ 中传播,则也就可以在 qss 中传播。

8. 命名空间中的 widget

类型选择器可用于为特定类型的 widget 设置样式。例如:

class MyPushButton : public QPushButton {
    
    // ...
}
qApp->setStyleSheet("MyPushButton { background: yellow; }");

Qt Style Sheet 使用 widget 的 QObject::className() 来确定何时应用类型选择器。当自定义部件在命名空间内时,QObject::className() 返回 ::,这与子控件的语法冲突。为了克服这个问题,在命名空间内使用类型选择器时,我们必须将“::”替换为“--”。 例如:

namespace ns {
    
    class MyPushButton : public QPushButton {
    
        // ...
    }
}
qApp->setStyleSheet("ns--MyPushButton { background: yellow; }");

9. 设置 QObject 属性

从 Qt 4.3 开始,可以使用 qproperty-<property name> 语法设置 Q_PROPERTY,例如:

MyLabel {
     qproperty-pixmap: url(pixmap.png); }
MyGroupBox {
     qproperty-titleColor: rgb(100, 200, 100); }
QPushButton {
     qproperty-iconSize: 20px 20px; }

如果该属性引用了一个用 Q_ENUMS 声明的枚举,您应该按名称引用它的常量,即,而不是它们的数值。

注意:请谨用 qproperty 语法,因为它会修改正在绘制的小部件。此外,qproperty 语法只评估一次,即当小部件被样式修饰时。这意味着在 QPushButton:hover 等伪状态下使用它们的任何尝试都将不起作用。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/ycyzrenlifei/article/details/126405024

智能推荐

基于QT4的TCP/UDP客户端程序设计_qt4 tcp-程序员宅基地

文章浏览阅读851次。文章转自: http://blog.sina.com.cn/s/blog_705adafb0101g00d.html设计一个基于QT的客户端程序,该程序使用tcp和udp与服务器端通讯,应用层协议为iec103协议,客户端与服务器端建立tcp连接,交互通讯流程采用tcp方式,定时报文传输采用udp方式,本客户端处理tcp和udp通讯,对应用层数据报文解析后提供回调接口供应用使用,并提供接口供应用..._qt4 tcp

maven项目:重新编译生成class文件_maven重新编译-程序员宅基地

文章浏览阅读1.3w次。原因:由于误删或更新了内容,且不能自动编译时,手动调节。解决步骤:手动clean-maven项目:项目==》右键:run as ==》maven clean 手动输入clean-maven命令:项目==》右键:run as ==》maven build ==》Goals:clean intall package ==》Apply Runclass文件重新生成:OK!..._maven重新编译

前端面试题集锦(一)-程序员宅基地

文章浏览阅读160次。温馨提示:经常看一些面试题,能够很好的对自己进行查缺补漏,检验自己的能力。1、写出transform中2D转换的几大属性及其作用:答:①translate():根据坐标原点,浏览器左上角(0,0)进行X轴、     Y轴上的位置移动    ②rotate():根据X轴进行旋转,正值时为顺时针,负值时为逆时针。(deg单位)    ③scale(parm1,parm2):根据原大小对其进行放大缩小功能,参数一二对应width和height,和X轴、Y轴。    ④skew(parm1,parm

功率的正负,无功,有功功率,容性感性功率_为什么充电功率是负的-程序员宅基地

文章浏览阅读1.8w次,点赞6次,收藏27次。功率当然有正负之分。比如两台并行的发电机发电驱动一台大功率用电设备。如果两台发电机没有协调好的话,很容易负载偏移,就是一台发电机承受负载大,领一台发电机承受负载小,而这种差距是会逐渐变大的,一直变到一台发电机承受所有的负载的同时,还要带另一台发电机转,另一台发电机不承受任何负载,还要被拉着转,这台发电机就属于负功率了。功率有正负之分所谓正负不应以功率消耗为标准,由于功率的定义是单位时间所做_为什么充电功率是负的

echarts图表的使用及用法-程序员宅基地

文章浏览阅读5.2k次。一、介绍ECharts,一个纯 Javascript 的图表库,可以流畅的运行在PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Safari等),底层依赖轻量级的 Canvas 类库 ZRender,提供直观,生动,可交互,可高度个性化定制的数据可视化图表。ECharts 提供了常规的折线图,柱状图,散点图,饼图,K线图,用于统计的盒形图,用于地理数据可视化的地图,热力图,线图,用于关系数据可视化的关系图,treemap,多维数据可视化的平行坐标,还_echarts图表

容器平台选型的十大模式:Docker、DC/OS、K8S 谁与当先?_开源容器平台-程序员宅基地

文章浏览阅读1.2k次。本文由 网易云 发布作者:刘超 来自:网易云基础服务无论是在社区,还是在同客户交流的过程中,总会被问到到底什么时候该用 Docker?什么时候用虚拟机?如果使用容器,应该使用哪个容器平台? 显而易见,我不会直接给大家一个答案,而是希望从技术角度进行分析具体的场景。例如客户是大公司还是小公司,将部署小集群还是大集群,倾向于私有云还是公有云,已经采购了 IaaS 还是没有 IaaS,IT 运维能力..._开源容器平台

随便推点

springboot gradle 使用过程中遇到的问题小结(6)_android expected a single classpath entry, found: -程序员宅基地

文章浏览阅读194次。1. 报错:Cannot deserialize instance of java.lang.String out of START_OBJECT token,我这里报这个错的原因是传递的json数据类型不对,修正后即可2. 使用JsonFormat引起的时间比正常时间慢8小时,@JsonFormat(pattern = "yyyy-MM-dd HH:mm", timezone = "GM..._android expected a single classpath entry, found: []

16.忽略大小写的字符串比较_16:忽略大小写的字符串比较-程序员宅基地

文章浏览阅读4.3k次。描述一般我们用strcmp可比较两个字符串的大小,比较方法为对两个字符串从前往后逐个字符相比较(按ASCII码值大小比较),直到出现不同的字符或遇到'\0'为止。如果全部字符都相同,则认为相同;如果出现不相同的字符,则以第一个不相同的字符的比较结果为准(注意:如果某个字符串遇到'\0'而另一个字符串还未遇到'\0',则前者小于后者)。但在有些时候,我们比较字符串的大小时,希望忽略字母的大小_16:忽略大小写的字符串比较

使用labelme制作自己的语义分割数据集_使用labelme训练自己的语义分割流程-程序员宅基地

文章浏览阅读1.4k次,点赞2次,收藏24次。安装labelme在cmd中激活我们使用的python环境,然后使用pip命令安装labelme,命令如下:pip install labelme==3.16.7注意:如果安装最新版本的 labelme,就无须指定版本号(3.16.7就是版本号)打开labelme在cmd中激活我们使用的python环境,然后使用下面的命令,就可以打开labelme软件:labelme界面如下图:使用labelme对数据集进行标注标注之前我们可以先设置一下自动保存:file——>Sav_使用labelme训练自己的语义分割流程

跟随小破站学习java web第十五天_小破站的学习陪伴-程序员宅基地

文章浏览阅读262次。file_upload.jsp<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><h..._小破站的学习陪伴

java解析定长文件入库_java-当直到运行时才知道记录布局时,使用哪种方法来解析具有固定长度记录的文件?...-程序员宅基地

文章浏览阅读392次。我想基于另一个文件中提供的记录布局来解析文件.基本上会有一个定义文件,它是一个用逗号分隔的字段及其各自长度的列表.其中会有很多,每次我运行程序时都会加载一个新的.firstName,text,20middleInitial,text,1lastName,text,20salary,number,10然后,我将显示一个带有提供的列标题的空白表,以及一个通过单击按钮或其他方式添加数据的选项-我尚未决定..._java 文本文件定长记录

week10限时大模拟_B -团队聚餐_s,vb不是在你那边可能在部门聚餐:u女包~、{k:↑二:、:-程序员宅基地

文章浏览阅读178次。B - 团队聚餐题目描述TA团队每周都会有很多任务,有的可以单独完成,有的则需要所有人聚到一起,开过会之后才能去做。但TA团队的每个成员都有各自的事情,找到所有人都有空的时间段并不是一件容易的事情。给出每位助教的各项事情的时间表,你的任务是找出所有可以用来开会的时间段。输入格式第一行一个数T(T≤100),表示数据组数。对于每组数据,第一行一个数m(2 ≤ m ≤ 20),表示TA..._s,vb不是在你那边可能在部门聚餐:u女包~、{k:↑二:、:

推荐文章

热门文章

相关标签