【Qt】Qt样式表/QSS基本语法

注意:

  • 本文为个人学习总结,不对的地方还请各位指出;
  • 谢绝任何形式的转载!

1 背景

1.1 从Web前端说起

World Wide Web Consortium (W3C) 将网页主要分为三个组成部分:

  • 结构(Structure) → HTML
  • 表现(Presentation) → CSS
  • 行为(Behavior) → JavaScript

一个设计良好的前端页面中,这三个部分应该相互分离又各司其职,这不管对于项目的开发还是后期维护都会更加友好。

1.2 回到Qt界面开发

在Qt中,结构、表现和行为可分别对应于.ui、.qss、c++(或其他)。Qt中的样式表有两种存在形式:

1).qss文件,通过程序将其设置到程序中(类似于web中的.css文件,外联样式);
2)直接写在.ui文件中(可在QDesigner中编写,类似于web中的行内样式)

1.3 盒模型(Box model)

在前端设计中,盒模型一个非常重要的概念。所有的部件都被视为有4个同心矩形的盒子(box),如图:
在这里插入图片描述

 - content rectangle:绘制窗口部件的内容的区域,如文字,图片;
 - padding rectangle:包围content rectangle,由padding属性指定填充操作,主要是窗口部件内容与边缘线(border)之间的空隙,由top,right,bottom和left设置他的大小;
 - border rectangle:包围padding rectangle,为边界预留空间,可认为是窗口的外框线;
 - margin rectangle:最外面的矩形,主要是负责与其他窗口部件间的距离。

QSS语法

Qt样式表的语法规则与HTML、CSS基本相同。

2.1 qss样式规则

在qss中,一个样式由选择器(selector)和声明(declaration)组成。其中,选择器确定了样式的作用对象,声明确定了作用于该对象的确切样式。如:

QPushButton 
{ 
	color: red 
}

在这段代码中,QPushButton为选择器(selector),{ color: red }为样式声明(declaration)。这段代码的作用是将所有QPushButton及其子类的前景色(文本颜色)设置为红色。

可以同时对多个对象设置样式,用逗号(,)来分隔选择器(selector)。如:

QPushButton, QLineEdit, QComboBox 
{
	color: red 
}

这与下面这段代码的作用是相同的:

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

声明(declaration)部分是由一个由多个<属性: 值>(键值对)组成的列表,由大括号({})包围并由分号(;)分隔开。如:

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

2.2 qss选择器

Qss中支持CSS2中定义的所有选择器(selector),下表为部分最常用的选择器(selector)。

选择器(selector)举例说明
通配选择器*匹配所有部件
类型选择器QPushButton匹配所有QPushButton及其子类的实例
属性选择器QPushButton[flat=“false”]匹配所有flat属性为false的QPushButton实例
类选择器.QPushButton匹配所有QPushButton的实例,但不包含其子类的实例
ID选择器QPushButton#okButton(或直接写#okButton)匹配所有object name(id)为okButton的QPushButton实例
后代/包含选择器QDialog QPushButton匹配所有QDialog中包含的所有QPushButton部件的实例,包括子、孙、子子孙孙部件
子选择器QDialog > QPushButton匹配QDialog的直接子控件QPushButton的实例

2.3 子控件

Qss中为复杂的部件定义了很多子控件,方便对于这些复杂部件的样式进行控制。如QComboBox的下拉按钮,以及QSpinBox的上下箭头。如:

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

这段代码设置了所有QComboBox的下拉按钮的样式。双冒号(::)语法让人想起CSS3中的伪元素,但这在Qt中的概念不同,并且具有不同的级联语义。

2.3.1 子控件绘制的参考矩形(subcontrol-origin)

可以使用subcontrol-origin属性来更改部件在其父部件中绘制的参考矩形,默认在padding的矩形中绘制。subcontrol-origin有margin、border、padding、content这4个值可供选择(对应盒模型中的4个矩形)。例如,我们想将drop-down子控件设置为参考margin矩形而不是默认的padding矩形来绘制,我们可以定义:

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

更近一步的例如,对一个QComboBox设置如下基本样式:

QComboBox 
{ 
	margin: 20px; 
	padding:20px; 
	border:20px solid blue; 
}

然后分别设置其子控件::drop-down的属性subcontrol-origin为margin、border、padding、content:

QComboBox::drop-down 
{ 
	subcontrol-origin: margin/border/padding/content; 
}

分别得到以下结果(注意观察下拉按钮的变化):
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

2.3.2 子控件的对齐(subcontrol-position)

通过上一节内容我们知道,可以使用subcontrol-origin属性设置子控件的绘制矩形区域,如margin rectangle。但是子控件一般不会与该矩形区域一样大,那么这时候子控件究竟应该绘制在哪个区域呢?答案是我们可以通过subcontrol-position属性来指定子控件的绘制位置,但不同子控件的默认绘制位置也是不同的。subcontrol-position属性在水平和垂直方向分别有left、center、right和top、center、bottom这几个值可以选择。

如,我们在上一节样式表的基础上为子控件添加subcontrol-position属性并分别设置水平方向为left、center、right这3个值(注意下拉按钮在水平方向位置的变化):
在这里插入图片描述在这里插入图片描述在这里插入图片描述

2.3.3 子控件的定位微调(position)

类似于CSS,在QSS中也有相对位置(position: relative)和绝对位置(position: absolute)的概念。

1)相对定位(position: relative)

可以用于改变子控件相对于其原始位置的偏移量。如,可用于实现点击按钮时的按下效果

QComboBox::down-arrow 
{
	image: url(down_arrow.png);
}
QComboBox::down-arrow:pressed 
{
	position: relative;
	top: 1px; 
	left: 1px;
}
2)绝对定位(position: absolute)

可以实现子控件的位置和大小随着参考部件的改变而改变。

2.4 伪状态选择器

选择器可以包含伪状态,用于根据部件的状态变换相应的样式。伪状态位于选择器的末尾,中间用冒号(:)隔开。
常用的伪状态有鼠标悬停(hover)、选中(checked)、按下(pressed)等。如下代码设置QPushButton在鼠标滑过时前景(文本)变为白色:

QPushButton:hover 
{ 
	color: white 
}

伪状态可以用感叹号(!)来表示否定。如:

QPushButton:!hover 
{ 
	color: white 
}

伪状态可以连接使用,这种情况下相当于隐含了一个逻辑“与”操作。如:

QCheckBox:hover:checked 
{ 
	color: white 
}

否定的伪状态也可以连接使用。如:

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

如果需要,也可以使用逗号操作来表示逻辑“或”。如:

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

伪状态也可以与子控件组合。如:

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

2.5 解决冲突

当样式中用不同的值指定了同一个属性时,就会出现冲突。如:

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

这两个规则都匹配了名为名为okButton的QPushButton实例,且color属性存在冲突。要解决这一冲突,我们必须考虑选择器(selector)的特殊性。在上面的示例中,QPushButton#okButton被认为比QPushButton更具体,因为他具体到某一对象,而不是所有类的实例。
同样的,具有伪状态的选择器比不指定伪状态的选择器更具体。如,以下样式表指定了当鼠标悬停在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)并且color属性存在冲突。因为QPushButton继承自QAbstractButton,所以可能很容易认为QPushButton比QAbstractButton更具体。但是,对于样式表的计算来说,所有的类型选择器都具有相同的特异性,并且最后出现的规则优先。换句话说,以上样式表会将所有QAbstractButton的颜色设置为灰色,包括QPushButton。如果我们希望QPushButton显示红色文本,我们可以对规则进行重新排序。

为了确定规则的特殊性,Qt样式表遵循CSS2规范:

选择器的特异性计算公式如下:

  • 计算选择器中ID属性的数量(=a)
  • 计算选择器中其他属性和伪状态类的数量(=b)
  • 计算选择器中元素名称的数量(=c)
  • 忽略伪元素[即子控制]

连接三个数字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 */

2.6 级联效应

QSS可以在QApplication、父部件和子控件上设置。任意部件上的有效样式表是通过组合设置在其祖先(父部件、祖父部件等)及QApplication中的样式得到的。

当冲突出现时,部件自身的样式表的优先级要高于任何由祖先部件集成过来的样式表。同时,父部件样式表的优先级要高于祖父部件的样式表。

比如,首先,我们在QApplication上设置样式表:

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

然后我们对QPushButton的对象设置样式表:

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

这样写的结果是:QPushButton样式表强制QPushButton(及其任何子控件)显示蓝色文字。

2.7 继承性

在经典的CSS中,当一个部件的字体和颜色等没有被明确设置时,它会从父级部件继承。但在QSS中,部件不会自动丛父级部件继承字体或颜色这些属性。

如,QGroupBox中包含QPushButton:

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

子控件QPushButton没有一个明确的颜色设置,因此子控件QPushButton不会继承其父部件QGroupBox的颜色,而是显示系统的默认颜色。如果要同时设置QGroupBox及其子控件的颜色,可以这样写:

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

与之相比,也可以通过QWidget::setFont()和QWidget::setPalette()来为子控件设置字体和颜色。

2.8 C++命名空间中的部件

类型选择器可用来设置某一特定类型部件的样式。如:

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

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

QSS使用部件的QObject::className()来确定何时应用类型选择器。当自定义的部件在命名空间中时,QObject::className()会返回::。这与子控件的语法冲突。为了解决这个问题,当命名空间内的部件使用类型选择器时,必须更换”::” 为 “–”。 例如:

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

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

2.9 设置对象属性

自从Qt4.3以后,任何可设计的Q_PROPERTY都可以通过qproperty-语法来设置。如:

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

参考资料

  • https://doc.qt.io/qt-5/stylesheet-syntax.html
  • 7
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: qt样式表葵花宝典.pdf是一本关于Qt样式表的指南。Qt是一种流行的C++开发框架,被广泛用于开发跨平台的应用程序。样式表是一种用于定义Qt应用程序外观和风格的工具。 该书中介绍了Qt样式表的基本概念和语法,以及如何使用样式表来修改应用程序的外观。通过使用样式表,开发人员可以轻松地自定义应用程序的界面,使之符合自己的需求和品味。 此外,该书还涵盖了如何使用Qt提供的预定义样式,以及如何创建自定义样式。它提供了大量的示例代码和实际应用案例,帮助读者深入理解和掌握Qt样式表的使用技巧。 Qt样式表葵花宝典.pdf对于希望在Qt应用程序中实现美观和个性化的界面的开发人员来说,是一本非常有价值的参考资料。无论是初学者还是有一定经验的开发者,都可以从中获得帮助和灵感。它为读者提供了一种简单而强大的方式来改变应用程序的外观,从而提升用户体验并增加应用程序的吸引力。 总之,Qt样式表葵花宝典.pdf是一本对于Qt开发者来说很有用的指南,它详细介绍了如何使用Qt样式表来定制应用程序的外观。无论您是初学者还是有经验的开发者,都可以从中学到很多实用的技巧和建议。 ### 回答2: 《Qt样式表葵花宝典.pdf》是一本关于Qt样式表的重要参考书籍。Qt样式表是一种用于美化和定制Qt应用程序外观的技术,该书详细介绍了Qt样式表的原理、语法和应用。 本书首先介绍了Qt样式表的基本概念和使用方法,包括如何在Qt应用程序中加载和应用样式表。然后,它系统地介绍了Qt样式表语法和各种样式属性的设置方法,例如背景色、字体、边框等。此外,书中还提供了许多实例和示例代码,帮助读者更好地理解和应用Qt样式表。 《Qt样式表葵花宝典.pdf》不仅适合初学者学习,也适合有一定经验的Qt开发者参考。无论是制作个性化的界面还是为商业应用设计专业的UIQt样式表都能提供强大的支持。 此外,该书还介绍了一些高级的Qt样式表技巧和工具,如如何自定义控件样式、使用QSS文件和资源文件等。这些内容对于想要深入研究和优化Qt应用程序外观的开发者来说是非常宝贵的。 总之,《Qt样式表葵花宝典.pdf》是一本权威且实用的Qt样式表指南,对于想要提升Qt应用程序外观设计水平的开发者来说是一本必备的参考书。无论是初学者还是有经验的开发者,都可以从中获得丰富的知识和技巧,进一步掌握和运用Qt样式表。 ### 回答3: 《Qt样式表葵花宝典.pdf》是一本关于Qt样式表使用和应用的指南。Qt样式表是用于定义Qt应用程序界面的外观和样式的一种技术。该书的作者通过详细介绍Qt样式表语法和属性,以及实际示例,帮助读者掌握如何使用Qt样式表来美化和定制Qt应用程序界面。 该书首先介绍了Qt样式表基本语法,包括选择器、属性和值的定义方式等。然后,通过演示不同的样式表属性和值的使用方法,让读者了解如何改变控件的颜色、字体、边框等外观属性,以及如何添加动画和效果等高级特性。此外,该书还展示了如何使用图片和图标来定制应用程序界面,以及如何创建自定义控件和布局。 《Qt样式表葵花宝典.pdf》不仅仅是一本技术手册,它还提供了许多实用的示例和技巧,帮助读者更好地理解和应用Qt样式表。无论是初学者还是有一定经验的Qt开发者,都能从该书中找到有用的信息和灵感,提升Qt应用程序的外观和用户体验。 总之,《Qt样式表葵花宝典.pdf》是一本对于学习和应用Qt样式表非常有帮助的指南。通过阅读该书,读者可以深入了解Qt样式表的使用技巧,掌握定制和美化Qt应用程序界面的方法,从而提升应用程序的质量和用户满意度。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值