Qt扫盲-QSS语法概述_qt qss-程序员宅基地

技术标签: QSS  qt5  QSS语法  Qt美化概述  # Qt扫盲  QSS语法概述  


概述:

  • QSS也叫Qt样式表,Qt样式表术语和语法规则几乎与HTML CSS的术语和语法规则相同。如果已经了解CSS,那就可能可以快速浏览本节。

一、语法规则

QSS 语法非常简单。样式规则由选择器和声明组成

  • 选择器指定哪些控件受规则影响
  • 声明指定应该在这个控件设置哪些属性。

就像下面:

QPushButton {
     color: red }

在上面的样式规则中,QPushButton是选择器,{color: red} 是声明。该规则指定QPushButton及其子类(例如,MyPushButton)应该使用红色作为它们的前色。

Qt样式表的声明通常不区分大小写(即color, Color, COLOR 和 cOloR 其实指的是同一个属性)。我一般都用小写的声明

唯一的例外是类名、对象名和Qt属性名,它们是区分大小写的,也即是选择器是区分的。

可以为同一个声明指定多个选择器,使用逗号(,)分隔这些选择器。例如,规则

QPushButton, QLineEdit, QComboBox {
     color: red }

等价于下面这个包含三条规则的序列:

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

样式规则的声明部分是一组属性:值对,用大括号({})括起来,用分号分隔。例如:

QPushButton {
     color: red; background-color: white }

控件的这些属性我到时候会在后面一篇博客里面记录一下。

二、选择器类型

选择器里面包含了子控件、伪态。

他们直接的关系是
选择器->子控件->伪态的,就行下面

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

Qt样式表支持 CSS2 中定义的所有选择器
在这里插入图片描述
下表总结了最有用,也是最常用的选择器类型。

用得最多的就是:类型选择器、ID 选择器、通配符选择器

选择器名 例子 解释
通配符选择器 * 匹配所有继承至QWidget的控件
类型选择器 QPushButton 匹配QPushButton及其子类的实例。
属性选择器 QPushButton[flat=“false”] 匹配非平的QPushButton实例。你可以使用这个选择器来测试任何支持QVariant::toString()的Qt属性(详细信息请参阅toString()函数文档)。此外,还支持特殊的class属性,用于表示类的名称。这个选择器也可以用来测试动态属性。有关使用动态属性进行自定义的更多信息,请参阅使用动态属性进行自定义。除了=,你还可以使用~=来测试QStringList类型的Qt属性是否包含给定的QString。警告:如果Qt属性的值在样式表设置之后发生了变化,可能需要强制重新计算样式表。实现这一点的一种方法是取消设置样式表并再次设置它。
类选择器 .QPushButton 匹配QPushButton的实例,但不匹配它的子类。和 类型选择器有区别。这相当于*[class~=“QPushButton”]。
ID 选择器 QPushButton#okButton 匹配所有对象名为okButton的QPushButton实例。也就是ObjectName 是 okButton,最常用
后代选择器 QDialog QPushButton 匹配QDialog的所有后代(子、孙辈等)QPushButton实例。匹配所有子代
后代选择器 QDialog > QPushButton 匹配QDialog的直接子QPushButton的所有实例。也即是只匹配子一代

这里的 属性选择器的属性 怎么看哈,其实可以在帮助文档里面查某一个类有哪些属性,属性是干嘛的,就行下面的QPushButton的属性,有flat 之类的,还跟页面相关。
在这里插入图片描述

三、子控件

因为某些复杂窗口组件的样式在父控件是设置不了的,就必须访问窗口组件的子控件,例如 QComboBox的 下拉按钮或QSpinBox的上下箭头。选择器可能包含子控件,使得可以将规则的应用直接设置限制到特定的控件 子控件。例如:

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

上面的规则为所有QCombobox的下拉按钮设置样式。虽然双冒号(::)的语法让人想起CSS3伪元素,但Qt子控件在概念上与它们有所不同,并且具有不同的级联语义。

子控件总是相对于另一个元素(引用元素)定位。这个引用元素可以是部件或另一个子控件。例如,默认情况下,QComboBox的::下拉框被放置在QComboBox的内边距矩形的右上角。默认情况下,::下拉位于::下拉子控件的内容矩形的中心。请参阅下面的可设置样式的窗口组件列表,以获取用于设置窗口组件样式及其默认位置的子控件。
可以使用subcontrol-origin属性更改要使用的原点矩形。例如,如果想把下拉框放在QComboBox的外边距矩形中,而不是默认的内边距矩形中,可以指定:

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

使用subcontrol-position属性更改下拉框在外边距矩形内的对齐方式。
width和height属性可以用来控制子控件的大小。请注意,设置图像会隐式地设置子控件的大小。这就需要手动设置那个子控件大小

相对定位方案(position: relative)允许子控件的位置偏离其初始位置。例如,当QComboBox的下拉按钮被按下时,我们可能希望其中的箭头被偏移,以产生“按下”的效果。为此,我们可以指定:

QComboBox::down-arrow {
    
      image: url(down_arrow.png);
}
QComboBox::down-arrow:pressed {
    
      position: relative;
      top: 1px; left: 1px;
}

绝对定位方案(position: absolute),允许子控件的位置和大小相对于参考元素进行更改。
一旦定位,它们就会被视为与窗口组件相同的部件,并可以使用box模型设置样式。
请参阅下面的子控件列表以获得支持的子控件列表,并自定义QPushButton的菜单指示子控件以获得一个实际示例。

注意:对于像QComboBox和QScrollBar这样的复杂部件,如果自定义了一个属性或子控件,那么所有其他属性或子控件也必须自定义。不然只设置一部分是不会生效的

四、伪态

选择器里面也是能有伪态的,表示根据控件 的状态限制规则的应用。伪状态出现在选择器的末尾,中间有一个冒号: 。
例如,当鼠标悬停在QPushButton上时,应用以下规则:

QPushButton:hover {
     color: white }

伪状态可以使用感叹号运算符求反。例如,当鼠标没有悬停在QRadioButton上时,应用以下规则:

QRadioButton:!hover {
     color: red }

伪状态可以被连接起来,在这种情况下,隐含了一个逻辑与。例如,当鼠标悬停在选中的QCheckBox上时,应用以下规则:

QCheckBox:hover:checked {
     color: white }

伪状态链中可能出现否定的伪状态。例如,当鼠标悬停在一个未按下的QPushButton上时,应用以下规则:

QPushButton:hover:!pressed {
     color: blue; }

如果需要,逻辑OR可以用逗号运算符表示:

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

伪状态可以与子控件结合出现。例如:

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

五、冲突解决

当多个样式规则用不同的值指定相同的属性时,就会产生冲突。在冲突时,基本原则就是越具体的对象的设置规则会覆盖低级别的

考虑下面的样式表:

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

这两个规则都匹配名为okButton的QPushButton实例,并且颜色属性存在冲突。为了解决这个冲突,我们必须考虑选择器的特异性。在上面的例子中,QPushButton#okButton被认为比QPushButton更具体,因为它(通常)引用单个对象,而不是类的所有实例。

类似地,带有伪状态的选择器比没有指定伪状态的选择器更特定。因此,下面的样式表指定当鼠标悬停在QPushButton上时,它应该是白色文本,否则是红色文本:

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

这里有一个棘手的问题:

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

在这里,两个选择器具有相同的特异性,因此如果鼠标在按钮启用时悬停在按钮上,则第二条规则优先。如果我们希望文本在这种情况下是白色的,我们可以像这样重新排列规则:

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

或者,我们可以让第一条规则更具体:这也是推荐使用的,越好懂的越好维护

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

与类型选择器一起出现类似的问题。考虑下面的例子:

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

这两个规则都适用于QPushButton实例(因为QPushButton继承了QAbstractButton),并且颜色属性存在冲突。因为QPushButton继承了QAbstractButton,所以很容易认为QPushButton比QAbstractButton更具体。

但是,对于样式表计算,所有类型选择器都具有相同的特异性,最后出现的规则优先。换句话说,所有QAbstractButtons(包括QPushButtons)的颜色都设置为灰色。如果我们真的想让QPushButtons有红色文本,我们总是可以重新排列规则。
为了确定规则的特异性,Qt样式表遵循CSS2规范:
选择器的特异性计算公式如下:

  • 计算选择器中ID属性的数量(= a)
  • 计算选择器中其他属性和伪类的数量(= b)
  • 计算选择器中元素名称的数量(= c)
  • 忽略伪元素[即子控件]。
    将a-b-c三个数字连在一起(在一个大基数的数字系统中)就具有了专一性。
    下面的是用的 Html 里面的样式举例
  *             {
    }  /* 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 */

六、样式层叠

所谓层叠,其实就是只多个样式表同时生效,同时作用于一个控件的某些属性的时候,是取优先级并集的,作为最后这个控件获取的样式表。

样式表可以在QApplication、父部件和子部件上设置。
任意控件的有效样式表是通过合并控件祖先(父级、祖父级等)上设置的样式表以及QApplication上设置的任何样式表来获得的。

当冲突发生时,控件 自己的样式表总是优先于任何继承的样式表,而不考虑冲突规则的特殊性。同样地,父部件的样式表优先于祖父部件的样式表,等等。
这样做的一个后果是,在控件 上设置样式规则会自动使其优先于在祖先控件 的样式表或QApplication样式表中指定的其他规则。考虑下面的例子。首先,我们在QApplication上设置了一个样式表:

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

然后我们在QPushButton对象上设置一个样式表:

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

QPushButton上的样式表强制QPushButton(和任何子部件)具有蓝色文本,尽管应用程序范围的样式表提供了更具体的规则集。
如果我们写信的话,结果是一样的

myPushButton->setStyleSheet("color: blue");

除了如果QPushButton有子元素(这是不太可能的),样式表不会对它们产生影响。

注意Qt目前没有实现 important 功能,Qt只采用了一部分的功能。

七、样式继承

在经典的CSS中,当一个项的字体和颜色没有显式设置时,它会自动从父项继承。默认情况下,当使用Qt样式表时,控件 件不会自动从其父控件 件继承其字体和颜色设置。
例如,考虑QGroupBox中的QPushButton:

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

QPushButton没有显式的颜色集。因此,它不继承其父QGroupBox的颜色,而是具有系统颜色。如果我们想在QGroupBox和它的子节点上设置颜色,我们可以这样写:

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

相反,使用QWidget::setFont()和QWidget::setPalette()设置字体和面板会传播到子部件。
如果你想让字体和调色板传播到子部件,你可以设置Qt::AA_UseStyleSheetPropagationInWidgetStyles标志,像这样:
用法:

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

当控件 样式的字体和调色板传播被启用时,通过Qt样式表所做的字体和调色板更改将表现为用户在样式表所针对的所有QWidget上手动调用了相应的QWidget::setPalette()和QWidget::setFont()方法。如果这将在c++中引起传播,同时也会在样式表中引起传播,反之亦然。

八、含命名空间样式设置

类型选择器可用于为特定类型的部件设置样式。例如,

class MyPushButton : public QPushButton {
    
      // ...
  }

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

Qt样式表使用小部件的QObject::className()来确定何时应用类型选择器。当自定义小部件位于名称空间中时,QObject::className()返回<名称空间>::<类名>。这与子控件的语法冲突。为了克服这个问题,在名称空间中的小部件使用Type Selector时,必须将“::”替换为“- -”。例如,

namespace ns {
    
      class MyPushButton : public QPushButton {
    
          // ...
      }
  }

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

九、QObject 属性设置

这个用的少,了解了解就好

从Qt 4.3开始,任何可设计的Q_PROPERTY都可以使用qproperty-<属性名>语法来设置。
例如,

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

如果属性引用用q_enum声明的枚举,则应该通过名称引用其常量,即,而不是它们的数值。
其实就是说,用Priority.High 而不是用 0

enum Priority {
     High, Low, VeryHigh, VeryLow };
Q_ENUM(Priority)

注意:请谨慎使用qproperty语法,因为它会修改正在绘制的部件。此外,qproperty语法只会被求值一次,这意味着任何尝试在伪状态(如QPushButton:hover)下使用它们都将不起作用。

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

智能推荐

mongodb 安装遇到问题:the domain,user name and/or password are incorrect.remember to use"." for the domain-程序员宅基地

文章浏览阅读3k次。安装mongoDB遇到如下问题:the domain,user name and/or password are incorrect.remember to use"." for the domain if the account is on the local machine解决:1.退出安装程序,第2步时选用custom2.重新安装到此步时,用默认选项安装如图:3.此处记得去掉勾..._the domain,user name and

Python3读取txt数据_python3 读取txt-程序员宅基地

文章浏览阅读3.4k次,点赞3次,收藏11次。从txt文件中导入数据1、操作步骤2、代码实现3、函数说明1、操作步骤(1)打开文件读取整个文件函数open返回一个表示文件的对象,对象存储在infile中。关键字with在不需要访问文件时将其自动关闭。读取出的内容以字符串形式保存在data1/data2里(2)第一种:读取所有行 infile.readlines()(3)第二种:每行分开读取 for循环 line.strip("\n").split()(4)第三种:每个字符分开读取 for循环-..._python3 读取txt

【云计算服务平台调研】阿里云、腾讯云、华为云对比_报告调研华为云平台的密码功能、服务、机制和/或接口等-程序员宅基地

文章浏览阅读5.2k次,点赞10次,收藏49次。云计算期末作业,调查云计算服务平台(阿里云、腾讯云、华为云)。_报告调研华为云平台的密码功能、服务、机制和/或接口等

JSP-程序员宅基地

文章浏览阅读151次。JSP一、JSP概述1.JSP(Java Server Pages)是由Sun公司倡导、多家公司参与,于1999年退出的一种动态网页技术标准。中文名叫Java服务器页,其根本是一个简化的Server设计。2.在HTML文件加入Java程序片段和JSP标记,就构成了JSP网页.3.JSP与Servlet的联系与区别JSP在本质上就是Servlet,但是两者的创建方式不一样,jsp运行时会被编译为Java文件。Servlet完全是Java程序代码构成,擅长于流程控制,通过Servlet来生成动态网页

给VSCode配置一下OpenCV-程序员宅基地

文章浏览阅读2.1k次。引言在运行opencv将16位灰度图片转化为8位的代码时遇到了以下错误。解决方案主要参考文章:【OpenCV】VScode下的OpenCV配置 - 吃土poQAQ - 博客园引言 最近开始着手学习OpenCV,因此需要配置一个OpenCV(C++)的环境。这篇文章大部分内容转载自网络,我会进行一些整理,并且加入一些我配置环境时遇到的问题与解决方法。参考连接我会写在文章末尾https://www.cnblogs.com/CTpoQAQ/p/13762428.html环境1. Open.

How to build NCL and NCAR Graphics from source code-程序员宅基地

文章浏览阅读261次。 NCAR CISL VETS Download Contributors Citing NCL NCL Examples Functions Resources Popular Links What's New Support External advanced..._fontconfig source code

随便推点

使用electron-builder打包过程中趟过的那些坑_electron-builder打包加密-程序员宅基地

文章浏览阅读1.8k次,点赞2次,收藏4次。electron-builder相比于electron-packager有更丰富的的功能,支持更多的平台,同时也支持了自动更新。除了这几点之外,由electron-builder打出的包更为轻量,并且可以打包出不暴露源码的setup安装程序。下面介绍一些electron-builder的使用方法:首先安装对应的打包工具,全局安装使用起来更方便npm intall electron-builder -g在项目的package.json文件中配置 electron-builder相关参数:_electron-builder打包加密

educoder警务大数据之离线存储_excel2003reader reader = new excel2003reader(new i-程序员宅基地

文章浏览阅读110次。【代码】educoder警务大数据之离线存储。_excel2003reader reader = new excel2003reader(new irowreader()

逆向工程_jar逆向工程-程序员宅基地

文章浏览阅读247次。逆向工程1.什么是逆向工程 1.mybatis需要程序员自己编写sql语句,mybatis官方提供逆向工程,可以针对单表自动生成mybatis执行所需要的代码(mapper.java,mapper.xml,po……) 2.企业实际开发中,常用逆向工程方式 3.由数据库的表生成java代码2.下载逆向工程所需jar包 mybatis-3.2.3.jar mybatis-generator-core-1.3.2.jar mysql-connector-java-5.1.28-bin.jar _jar逆向工程

JDK安装及环境变量配置-程序员宅基地

文章浏览阅读144次。JDK安装及环境变量配置1.到官网找到相应的JDK版本并下载JDK下载地址:https://www.oracle.com/cn/java/technologies/javase-downloads.html

latex插入代码块-程序员宅基地

文章浏览阅读6.8k次,点赞9次,收藏31次。插入matlab代码在开始加入\usepackage{listings}%插入代码块在需要添加代码的地方\begin{lstlisting}[language = Matlab,title={matlab4\_8.m}, numbers=left, numberstyle=\tiny,keywordstyle=\color{blue!70}, commentstyle=\color{red!50!green!50!blue!50},frame=shadowbox, ru_latex插入代码

【自定义函数】销售订单跟踪报表 -- 获取已开票领料套数-程序员宅基地

文章浏览阅读592次。 /****** Object: UserDefinedFunction [dbo].[fn_SO_GetIssuedQty] Script Date: 12/11/2009 08:53:15 ******/SET ANSI_NULLS ONGO SET QUOTED_IDENTIFIER ONGO /********************************** 销售订单跟

推荐文章

热门文章

相关标签