Qt之QSS(样式表语法)
http://blog.csdn.net/liang19890820/article/details/51691212
版权声明:进步始于交流,收获源于分享!纯正开源之美,有趣、好玩、靠谱。。。作者:一去丶二三里 博客地址:http://blog.csdn.net/liang19890820
简述
Qt样式表(以下统称QSS)的术语和语法规则几乎和CSS相同。如果你熟悉CSS,可以快速浏览以下内容。
样式规则
QSS包含了一个样式规则序列,一个样式规则由一个选择器和声明组成,选择器指定哪些部件由规则影响,声明指定哪些属性应该在部件上进行设置。例如:
QPushButton { color: red }
- 1
上面的例子中QPushButton是选择器,{ color: red }是声明,该规则指定QPushButton及其子类(例如:MyPushButton)应使用红色作为前景色。
QSS通常不区分大小写(即:color、Color、COLOR、cOloR指同一属性),唯一例外就是类名(class names)、对象名(object names)、属性名(property names)区分大小写。
几个选择器可以指定相同的声明,使用逗号(,)来分隔选择器。例如:
QPushButton, QLineEdit, QComboBox { color: red }
- 1
相当于三个规则序列:
QPushButton { color: red }
QLineEdit { color: red }
QComboBox { color: red }
- 1
- 2
- 3
声明部分的规则是一个属性值对(property: value)列表,包含在花括号中,以分号分隔。例如:
QPushButton { color: red; background-color: white }
- 1
参考助手:Qt Style Sheets Reference
中List of Properties
部分。
选择器类型
目前为止,所有的示例使用选择器中最简单的类型,类型选择器。QSS支持所有的selectors defined in CSS2。下表总结了最有用的类型选择器。
选择器 | 示例 | 说明 |
---|---|---|
通用选择器 | * | 匹配所有部件 |
类型选择器 | QPushButton | 匹配QPushButton及其子类的实例 |
属性选择器 | QPushButton[flat=”false”] | 匹配QPushButton中flat属性为false的实例。可以用此选择器来测试任何支持QVariant::toString() 的属性,此外,支持特殊的类属性、类名称。此选择器也可以用来测试动态属性(参考助手:Qt Style Sheets Examples 中Customizing Using Dynamic Properties 部分)。还可以使用~=替换=,测试QStringList类型的属性是否包含给定的QString。 警告:如果Qt属性值在设置样式之后更改,那么可能需要强制重新计算样式。实现的一个方法是取消样式,然后重新设置一遍。 |
类选择器 | .QPushButton | 匹配QPushButton的实例,但不包含子类。相当于*[class~=”QPushButton”]。 |
ID选择器 | QPushButton#okButton | 匹配所有objectName为okButton的QPushButton实例。 |
后代选择器 | QDialog QPushButton | 匹配属于QDialog后代(孩子,孙子等)的QPushButton所有实例。 |
子选择器 | QDialog > QPushButton | 匹配属于QDialog直接子类的QPushButton所有实例。 |
子控件
对于样式复杂的部件,需要访问子控件,例如:QComboBox的下拉按钮或QSpinBox的上下箭头。选择器可能包含子控件,使得可以限制特有部件子控件的应用规则。例如:
QComboBox::drop-down { image: url(dropdown.png) }
- 1
上述规则指定了QComboBoxe下拉按钮样式,虽然双冒号(::)语法让人想起CSS3伪元素,但Qt子控件从概念上讲有不同的级联语义。
子控件定位总是相对于另一个参考元素。这个参考元素可能是小部件或其它子控件。例如:QComboBox的::drop-down放置,默认的放置在QComboBox区域的右上角,::drop-down放置,默认的在::drop-down子控件的中央,参考助手:Qt Style Sheets Reference
中List of Stylable Widgets
部分。
可以使用subcontrol-origin改变子控件原始的默认位置,
QComboBox {
margin-right: 20px;
}
QComboBox::drop-down {
subcontrol-origin: margin;
}
- 1
- 2
- 3
- 4
- 5
- 6
下拉的对齐方式可以通过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;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
绝对定位(position : absolute):允许子控件改变位置和的大小而不受参考元素限制。一旦位置被设定,这些子控件将被和普通部件(widgets)视为相同,并且可以使用盒模型样式(参考助手:Customizing Qt Widgets Using Style Sheets
中The Box Model
部分)。
参考助手:Qt Style Sheets Reference
中List of Sub-Controls
部分,及Qt Style Sheets Examples
中Customizing the QPushButton's Menu Indicator Sub-Control
部分。
注意:对于复杂的部件,如:QComboBox和QScrollBar,如果一个属性或子控件被定制,所有其它属性或子控件必须被定制好。
伪选择器
选择器可以包含伪状态,意味着限制基于部件状态的应用程序规则。伪状态出现在选择器后面,用冒号(:)关联。例如,鼠标划过按钮:
QPushButton:hover { color: white }
- 1
伪状态可以用感叹号(!)运算符表示否定。例如,当鼠标不划过QRadioButton:
QRadioButton:!hover { color: red }
- 1
伪状态可以连接使用,这种情况下,相当于隐含了一个逻辑与。例如,当鼠标滑过选中的QCheckBox:
QCheckBox:hover:checked { color: white }
- 1
否定的伪状态也可以连接使用,例如,当鼠标划过一个非按下时按钮:
QPushButton:hover:!pressed { color: blue; }
- 1
如果需要,也可以使用逗号操作来表示逻辑或:
QCheckBox:hover, QCheckBox:checked { color: white }
- 1
伪状态也可以与子控件组合,例如:
QComboBox::drop-down:hover { image: url(dropdown_bright.png) }
- 1
参见助手:Qt Style Sheets Reference
中List of Pseudo-States
部分。
解决冲突
当样式中指定相同的属性具有不同的值时,就会出现冲突。例如:
QPushButton#okButton { color: gray }
QPushButton { color: red }
- 1
- 2
两个规则匹配objectName为okButton的QPushButton实例,color属性有冲突。要解决这个冲突,必须考虑到的选择器的特殊性。上面的例子,QPushButton#okButton被认为比QPushButton更具体,因为它通常是指单个对象,而不是一类的所有实例。
同样的,利用伪状态比不指定伪状态那些选择器更具体。因此,下面的样式指定一个QPushButton应该有鼠标悬停文本白色,否则文本红色效果:
QPushButton:hover { color: white }
QPushButton { color: red }
- 1
- 2
这里有一个复杂的:
QPushButton:hover { color: white }
QPushButton:enabled { color: red }
- 1
- 2
这里,两个选择器有相同的特殊性,如果鼠标在按钮上时,第二条规则优先。如果在这种情况下我们想要白色文本,需要重新排序规则:
QPushButton:enabled { color: red }
QPushButton:hover { color: white }
- 1
- 2
或者,可以使第一条规则更加具体:
QPushButton:hover:enabled { color: white }
QPushButton:enabled { color: red }
- 1
- 2
类似的问题出现在类型选择器一起使用。请看下面的例子:
QPushButton { color: red }
QAbstractButton { color: gray }
- 1
- 2
两个规则应用于QPushButton实例(因为QPushButton继承自QAbstractButton)并有color属性的冲突。因为QPushButton继承QAbstractButton,所以QPushButton比QAbstractButton更具体。
然而,对于QSS的计算,所有的类型选择具有相同的特殊性,最后出现的规则优先。换句话说,所有的QAbstractButton颜色设置为灰色(包括QPushButton)。如果需要设置QPushButtons为红色文字,我们总能重新排序规则。
为了确定一个规则的特殊性,QSS遵循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 */
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
级联效应
QSS可以在QApplication、父部件、子部件中设置。任意部件的有效样式表通过合并部件的祖先(父亲,祖父等)以及任何QApplication上设置的样式表。
冲突发生时,不论冲突规则的特殊性,部件自身的样式表总优先于任何继承样式表。同样,父窗口部件样式表优先于祖父等。
这样,一个部件设置样式自动使得它比在祖先部件或QApplication的样式表中指定的其它规则的优先级高。考虑下面的例子。首先,我们在QApplication中设置样式表:
qApp->setStyleSheet("QPushButton { color: white }");
- 1
然后,我们设置QPushButton的样式表:
myPushButton->setStyleSheet("* { color: blue }");
- 1
QPushButton样式表强制QPushButton(以及任何子部件)显示蓝色文字,尽管应用程序范围内的样式表提供的规则更具体。
如果按照下面这种方式写,其结果是相同的:
myPushButton->setStyleSheet("color: blue");
- 1
但如果QPushButton有孩子(不太可能),样式表就不会对它们有效果。
样式表级联是一个复杂的话题。请参考CSS2 Specification,要知道目前Qt没有实现。
继承性
在经典的CSS中,当字体和颜色没有明确设置时,它就会自动从父继承。当使用QSS时,部件不会自动从父继承字体和颜色。
例如,一个QGroupBox中包含QPushButton:
qApp->setStyleSheet("QGroupBox { color: red; } ");
- 1
QPushButton没有一个明确的颜色设置,因此,不是继承其父QGroupBox的颜色,而是显示系统的颜色。如果要建立一个QGroupBox及其孩子的颜色,可以这样写:
qApp->setStyleSheet("QGroupBox, QGroupBox * { color: red; }");
- 1
相比之下,可以用QWidget::setFont() 和 QWidget::setPalette()为子部件设置字体和画板 。
Namespaces中的部件
类型选择器可用于某一特定类型的部件。例如:
class MyPushButton : public QPushButton {
// ...
}
// ...
qApp->setStyleSheet("MyPushButton { background: yellow; }");
- 1
- 2
- 3
- 4
- 5
- 6
QSS使用部件的QObject::className()来确定何时应用类型选择器。当自定义的部件在命名空间中时,QObject::className()返回<namespace>::<classname>
。这与子控件的语法冲突。为了解决这个问题,当命名空间内的部件使用类型选择器时,必须更换”::” 为 “–”。 例如:
namespace ns {
class MyPushButton : public QPushButton {
// ...
}
}
// ...
qApp->setStyleSheet("ns--MyPushButton { background: yellow; }");
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
设置对象属性
从4.3及以后,任何可被识别的Q_PROPERTY都可以使用qproperty-<property name>
语法设置。
例如:
MyLabel { qproperty-pixmap: url(pixmap.png); }
MyGroupBox { qproperty-titleColor: rgb(100, 200, 100); }
QPushButton { qproperty-iconSize: 20px 20px; }
- 1
- 2
- 3
如果属性引用Q_ENUMS声明的枚举,则应该参考其常量的名字,而不是数值。
Qt之QSS(样式表语法)的更多相关文章
- pyqt样式表语法笔记(下)--原创
pyqt样式表语法笔记(下) python 启动界面 QSS pyqt 一.启动界面的设置 简单点~说话的方式简单点用一张静态图片作为程序启动界面为例. 原来的语句 python 7行 ...
- pyqt样式表语法笔记(上) --原创
pyqt样式表语法笔记(上) pyqt QSS python 样式表 因为软件课设的原因开始学习使用pyqt4,才发现原来它也有样式表,而且语法跟css基本相同,而且一些功能实现起来感觉比js要简单方 ...
- pyqt样式表语法笔记
pyqt样式表语法笔记 pyqt QSS python 样式表 因为软件课设的原因开始学习使用pyqt4,才发现原来它也有样式表,而且语法跟css基本相同,而且一些功能实现起来感觉比js要简单方便得多 ...
- pyqt样式表语法笔记(中)--原创
pyqt样式表语法笔记(中) pyqt QSS python 样式表 一.弹窗 在日常的各种桌面软件的使用中,我们都会碰到弹窗.例如注册,登录的时候,会有相应的信息弹窗,这里就以信息收集弹窗为例进行弹 ...
- pyqt样式表语法笔记(中)
pyqt样式表语法笔记(中) pyqt QSS python 样式表 一.弹窗 在日常的各种桌面软件的使用中,我们都会碰到弹窗.例如注册,登录的时候,会有相应的信息弹窗,这里就以信息收集弹窗为例进行弹 ...
- Qt的Qss样式
http://www.cnblogs.com/coffeegg/archive/2011/11/15/2249452.html(转) http://blog.csdn.net/cgzhello1/ar ...
- Qt之QSS(白色靓丽)
简述 Qt助手中有关于各种部件的QSS详细讲解,资源很丰富,请参考:Qt Style Sheets Examples. 白色靓丽 - 一款漂亮的QSS风格. 你可以直接使用,也可以随意转载,但请务必保 ...
- Qt之QSS(黑色炫酷)
简述 Qt助手中有关于各种部件的QSS详细讲解,资源很丰富,请参考:Qt Style Sheets Examples. 黑色炫酷 - 一款漂亮的QSS风格. 之前博客中分享了很多关于Qt的样式效果,几 ...
- Qt之QSS(QDarkStyleSheet)
简述 关于样式,前面介绍了很多内容,下面分享一个深色样式表,很值得借鉴! 简述 效果 QSS 更多参考 效果 QSS /* * The MIT License (MIT) * * Copyright ...
- 自学QT之qss教程
这篇文章来自于QT的帮助文档,你要是看了最新版的,会发现讲解得更棒.如果你的英文不是那么好,或者说看着头疼,那还是来看此篇吧. 在此之前说一个帮助文档的特别用法,绝不仅仅是搜单词,QT的文档非常强大的 ...
随机推荐
- 【算法笔记】B1014 福尔摩斯的约会
1014 福尔摩斯的约会 (20 分) 大侦探福尔摩斯接到一张奇怪的字条:我们约会吧! 3485djDkxh4hhGE 2984akDfkkkkggEdsb s&hgsfdk d&Hy ...
- LOJ6502. 「雅礼集训 2018 Day4」Divide(构造+dp)
题目链接 https://loj.ac/problem/6502 题解 中间一档部分分提示我们将所有的 \(w_i\) 排序. 考虑如果我们能构造出这样一个 \(w_i\) 的序列,使得该序列满足:对 ...
- A. Little C Loves 3 I Codeforces Round #511 (Div. 2) 【数学】
题目: Little C loves number «3» very much. He loves all things about it. Now he has a positive integer ...
- mongodb 增查改删
我们在 MongoDB 之 你得知道MongoDB是个什么鬼 MongoDB - 1 中学习了如果安装部署一个 MongoDB 如果没看到我的金玉良言的话,就重新打开一次客户端和服务端吧 本章我们 ...
- (转)Openldap相关精品文章
1.运维咖啡吧 https://mp.weixin.qq.com/s__biz=MzU5MDY1MzcyOQ==&mid=2247483754&idx=1&sn=9f20d45 ...
- python学习10-内置函数 迭代 二分法/面向对象初识(转载)
一.匿名函数 形式: lambda 形参:返回值 lambda表示的是匿名函数. 不需要用def来声明, 一句话就可以声明出一个函数.匿名函数不是说一定没名字,而是他们的名字统一称为“lambda”, ...
- Android应用中添加Log4j的示例
[2016-06-30]最新的log4j已经集成在DR_support_lib库中 具体请看: https://coding.net/u/wrcold520/p/DR_support_lib/git/ ...
- Python学习 day08
一.open打开文件 文件操作包含以下三个步骤: 1.文件路径 2.编码方式 3.操作方式:‘’只读‘’.“只写”.“读写” 等 1.只读 r (mode默认值) 例: f = open('d:\py ...
- springboot+Zookeeper+Dubbo入门
最近想学习dubbo,就利用周末写了一个特别简单的demo,不知道有没有用,先记录一下. 1.安装zookeeper并启动(安装看我上一篇博客https://www.cnblogs.com/huang ...
- python 获取子目录下的所有文件的路径
import os pathss=[] for root, dirs, files in os.walk(tarpath): path = [os.path.join(root, name) for ...