Qt 之 样式表使用过程中的冲突

本文详细解释了在Qt样式表中出现样式冲突的原因,并通过具体示例介绍了如何根据选择器的特殊性解决这些冲突。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、简述

我们在给控件设置样式的过程中,难免会有所冲突,那冲突究竟是怎么产生的呢?

我们看下面的样式设置,第一条样式使用了ID选择器,给objectName为”okButton”、类型为QPushButton的实例设置字体颜色为灰色

而第二条样式使用了类型选择器,给类型为QPushButton的实例设置字体颜色为红色,这里我们发现这条样式同样适用于第一条样式选择的实例,且两条样式都是设置颜色属性,这里就产生了冲突。

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

所以这里的样式冲突可以简单地理解为:两条或多条样式对某个控件实例的同一个属性设置了不同的属性值

为了解决冲突,我们可以根据样式选择器的特殊性,哪个更特殊,哪个设置的样式就生效,而且与样式的顺序没有关系。在上面的例子中,我们看到使用QPushButton#okButtonQPushButton更加特殊,因为前者在后者的基础上加上了ID(objectName)选择,一般ID选择器只会针对某一个控件实例设置样式(当然也可以使用setObjectName设置相同的ID,对多个控件实例设置样式),而QPushButton则会设置所有QPushButton实例的样式。

所以objectName为”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更加特殊呢?

答案是否定的,对于Qt的样式表而言,所有的类型选择器都具有同样的特殊性而后设置的样式占有优先权。就上面样式而言,所有QAbstractButton按钮(包括继承自QAbstractButton的按钮,如QPushButton、QToolButton等类型按钮)字体颜色都会设置成灰色。如果想让QPushButton类型按钮字体颜色设置为红色,那就调换两条样式的位置即可。


那么我们如何判断一个样式的特殊性呢,Qt样式表遵循CSS2 Specification :

选择器的特殊性计算规则如下:

这里写图片描述

以上这个计算方法暂时没有完全搞懂,所以先附上一张图,后续整理好了再继续完善。

以上内容根据Qt文档中叙述加上自己的理解简单整理一下,在使用样式表的过程中,当两条或多条样式对某个控件实例的同一个属性设置了不同的属性值时,到底哪一个样式设置会有效

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值