从零开始学Qt(20)QSS详解(2)QSS语法
QSS的术语和语法规则几乎与HTML CSS相同。如果你已经了解CSS,可以快速浏览本文。样式规则
样式表由一系列样式规则组成。样式规则由选择器(selector)和声明(declaration)组成。选择器指定哪些widgets受规则影响;声明指定应在widget上设置哪些属性。例如:QPushButton { color: red }
在上面的样式规则中,QPushButton是选择器,{color:red}是声明。该规则指定 QPushButton及其子类(例如MyPushButton)使用红色作为其前景色。
QSS通常不区分大小写(即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 }选择器类型
到目前为止,所有示例都使用了最简单的选择器类型,即类型选择器。QSS支持CSS2中定义的所有选择器。下表总结了最有用的选择器类型。
辅助控制器(sub-control)
要设置复杂widgets的样式,必须利用widget的辅助控制器(相当于子控件),例如QComboBox的下拉按钮或QSpinBox的上下箭头。选择器可能包含特定的辅助控制器,以便限制规则的应用。例如:QComboBox::drop-down { image: url(dropdown.png) }
上述规则设置了所有QComboBox的下拉按钮的样式。虽然双冒号(::)语法让人想起CSS3的伪元素,Qt辅助控制器在概念上与这些不同,并且具有不同的级联语义。
辅助控制器始终相对于另一个元素(参考元素)声明。此参考元素可以是widget或是其他辅助控制器。
可以使用subcontrol-origin属性更改要使用的源矩形。例如,如果我们想将下拉列表放在QComboBox的边距矩形(margin rectangle)而不是默认的填充矩形(Padding rectangle)中,我们可以指定: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),允许相对于参考元素更改子控件的位置和大小。
定位后,它们被视为与widget相同,并且可以使用框模型(box model)设置样式。
注意: 对于复杂的widget(如QComboBox和QScrollBar),如果自定义了一个属性或子控件,则还必须自定义所有其他属性或子控件。伪态(Pseudo-States)
选择器可以包含伪态,表示根据widget的状态限制规则的应用。伪态出现在选择器的末尾,用冒号分隔。例如,当鼠标悬停在QPushButton上时,以下规则适用:QPushButton:hover { color: white }
可以使用感叹号运算符对伪态进行求反。例如,当鼠标未悬停在QRadioButton上时,以下规则适用:QRadioButton:!hover { color: red }
伪态可以链接使用,在这种情况下,逻辑AND是隐含的。例如,当鼠标悬停在选中的 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实例,并且color属性存在冲突。为了解决这种冲突,我们必须考虑选择器的特异性(specificity)。在上面的例子中,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 更具体。但是对于样式表,所有类型选择器都具有相同的特异性,规则为最后出现的优先。换句话说,所有QAbstractButtons(包括QPushButtons)的颜色都设置为灰色。如果我们真的希望QPushButton有红色文本,我们可以随时对规则重新排序。
为了确定规则的特异性,QSS遵循CSS2的规范。
选择器的特异性计算如下:计算选择器中ID属性的数量(= a) 计算选择器中其他属性和伪类(pseudo-classes)的数量(= b) 计算选择器中的元素名称数(= c) 忽略伪元素 [即subcontrols]。 三个数字运算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 */级联(Cascading)
样式表可以在QApplication、父控件和子控件上设置。任意widget的有效样式表是通过合并widget的所有父控件上的样式表以及QApplication上的任何样式表来获得的。
当发生冲突时,无论冲突规则的特异性如何,widget自己的样式表始终优先于任何继承的样式表。同样,父控件的样式表优先于祖控件的样式表等。
这样做的一个结果是,在widget上设置样式规则会自动使其优先于祖控件的样式表或 QApplication样式表中指定的其他规则。请考虑以下示例。首先,我们在QApplication上设置一个样式表:qApp->setStyleSheet("QPushButton { color: white }");
然后我们在QPushButton对象上设置一个样式表:myPushButton->setStyleSheet("* { color: blue }");
QPushButton上的样式表强制QPushButton(和任何子控件)具有蓝色文本,尽管应用程序范围内的样式表提供了更具体的规则集。
以下方式结果也是相同,myPushButton->setStyleSheet("color: blue");
除非QPushButton有子项(这不太可能),样式表对它们没有影响。继承
在经典CSS中,当项目的字体和颜色未显式设置时,它会自动从父项继承。默认情况下,使用Qt样式表时,widget不会自动从其父控件继承其字体和颜色设置。
例如,考虑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);C++命名空间中的widget
类型选择器可用于设置特定类型的widget的样式。例如class MyPushButton : public QPushButton { // ... } // ... qApp->setStyleSheet("MyPushButton { background: yellow; }");
QSS使用widget的QObject::className()来确定何时应用类型选择器。当自定义widget位于命名空间内时,QObject::className()返回::。这与辅助控制器的语法冲突。为了克服这个问题,当对命名空间中的widget使用类型选择器时,我们必须将"::"替换为"--"。例如namespace ns { class MyPushButton : public QPushButton { // ... } } // ... qApp->setStyleSheet("ns--MyPushButton { background: yellow; }");设置QObject属性
从4.3及更高版本开始,任何可设计的Q_PROPERTY都可以使用qproperty-<属性名称> 语法进行设置。例如MyLabel { qproperty-pixmap: url(pixmap.png); } MyGroupBox { qproperty-titleColor: rgb(100, 200, 100); } QPushButton { qproperty-iconSize: 20px 20px; }
如果属性引用Q_ENUMS声明的枚举,则应按名称引用而不是它们的数值。
注:请谨慎使用qproperty语法,因为它会修改正在绘制的widget。此外,qproperty语法只应用一次,即widget被样式润色时。这意味着不能在任何伪态(如QPushButton:hover)中使用它们。
新疆文旅厅请不要让独库公路变成垃圾场最近,不少网友反映,在新疆独库公路看见垃圾乱扔的现象,尤其在停车区休息站等场所,食品袋塑料瓶遍地都是。除了自驾热门独库公路,还有徒步爱好者钟情的乌孙古道的天堂湖热门景点琼库什台村等
步步惊心变成悔恨终生,谁在把游客的性命当儿戏?抓紧了,抓紧了千万不能松手,坚持住!不行了,要掉下去了7月22日,湖北恩施4A级景区恩施地心谷,天津蓟州区九山顶景区,接连发生两起步步惊心游客坠落事故。事发时的视频被游客拍下,在社
新疆独库公路变垃圾公路,野外出游如何不伤美景?澎湃新闻记者何沛芸实习生肖霞洁近日,新疆独库公路垃圾遍地话题在网络引发网友关注。7月24日,新疆维吾尔自治区文化和旅游厅官方公众号发布文章倡议,请自驾游客随车携带垃圾袋,将垃圾投放
广东又一清凉2日游好去处,住五星酒店,豪砌海鲜大餐,超大泳池广东江门东古玥湖酒店,两人599抢秀湖园景房自助早餐豪华海鲜自助晚餐点开我的头像,再点底部活动资讯,搜索关键词东古下单预定我们面前迷人的风景迫使人们仔细收集。氡元素温泉是从杜府进口
今晚发售!同程旅行推出燃油消消卡机建燃油费全免CNMO新闻在中长距离的出行中,乘坐飞机是一个很不错的选择,但7月5日以来,燃油附加费收取标准再度上调,成人票收费政策为800公里(含)以下航线每位旅客收取人民币100元,800公
1989年邓小平舅舅去世,县委请示丧礼标准,邓小平只交代了三句话在阅读此文之前,麻烦您点击一下关注,既方便您进行讨论与分享,又给您带来不一样的参与感,感谢您的支持!前言翻身不忘共产党,致富更思邓小平。来到邓小平故居附近,这句名言警句随处可见。为
自驾游适合什么轮胎?看完这篇不再纠结佳通越野AT100人生至少要有两次冲动,一为奋不顾身的爱情,二为说走就走的旅行。如今,长途自驾游成为很多人热衷的旅游方式,我们在享受沿途风景的同时,车辆所面临的路况也是复杂多变。而
太仓这些宝藏地,大人小孩都爱去如果说这世界上有一种玩具会让全世界的大朋友一见倾心小朋友欢呼雀跃大概就是沙子和水吧疫情还未退散去不了浪漫的马尔代夫和三亚没关系!在江南宝地金太仓同样也能解锁夏日玩沙嬉水的乐趣小融为
中医养生一张表告诉你,什么体质喝什么茶,你喝对了吗?不管是喝什么茶适当的场合时间人喝适当的茶那样才能发挥最好的效果起到很好的保健功效中医认为人的体质有燥热虚寒之别而茶叶经过不同的制作工艺也有凉性及温性之分所以体质各异饮茶也有讲究接着
喝酒的妙处我父亲不太长寿我们都以为与酒有关。他喝了一辈子酒,晚年得了时髦的酒依赖症。先前家庭是比较困难的,但因父亲爱酒,使我很小时侯就有对酒的体验。少年时我很弱小,却因一直有喝酒的机会而使酒
关节痛吃氨糖是否有效?能否天天吃?看看临床医生怎么说氨糖相信绝大多数人都比较陌生。氨糖全称氨基葡萄糖属于骨关节炎一种补充剂。氨糖用于治疗关节炎的时间比较长,绝大多数患者在服用氨糖之后,关节炎也得到了恢复。因此至今为止,氨糖依然被用于