Qt Style Sheets

样式表语法

        Qt 样式表术语和语法规则几乎与 HTML CSS 的相同。如果您已经了解 CSS,您可能可以快速浏览此部分。

样式规则

        样式表由一系列样式规则组成。样式规则由选择器和声明组成。选择器指定哪些小部件受该规则影响;声明指定应在小部件上设置哪些属性。例如:

QPushButton { color: red }

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

        Qt 样式表通常不区分大小写(即 colorColorCOLOR 和 cOloR 指的是相同的属性)。唯一的例外是类名、对象名 和 Qt 属性名,它们区分大小写。

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

QPushButton, QLineEdit, QComboBox { color: red }

        相当于以下这三条规则的序列:

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

        样式规则的声明部分是一系列property: value对,括在花括号({})中,并以分号分隔。例如:

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

        请查看下面的属性列表部分,以获取 Qt 控件提供的属性列表。

选择器类型

选择器类型
选择器示例解释实例代码
通用选择器*匹配所有小部件。
* { background-color: red; }///< 通用选择器:设置所有控件的背景颜色为红色

类型选择器QPushButton匹配 QPushButton 及其子类的实例。
QWidget { background-color: red; }///< 将应用样式到所有的 QWidget 类型的部件上,将背景颜色设置为红色。

属性选择器QPushButton[flat="false"]

匹配不是扁平QPushButton实例。您可以使用此选择器来测试支持QVariant::toString()的任何 Qt属性(有关详细信息,请参阅toString()函数文档)。此外,还支持特殊的class属性,用于类的名称。

此选择器还可用于测试动态属性。有关使用动态属性进行自定义的更多信息,请参阅使用动态属性进行自定义

与其使用=,您还可以使用~=来测试类型为QStringList的 Qt 属性是否包含给定的QString

警告:如果在设置样式表后 Qt 属性的值发生更改,可能需要强制重新计算样式表。实现此目的的一种方法是取消设置样式表然后再次设置。

QWidget[focus = true] { background-color: red; }///< 当 QWidget 具有 focus 属性且值为 true 时,应用背景颜色为红色的样式。
QPushButton[enabled = false] { color: gray; }///< 当 QPushButton 的 enabled 属性为 false ,将其文字颜色设置为灰色。

类选择器.QPushButton

匹配 QPushButton 的实例,但不包括其子类。

这等同于 *[class~="QPushButton"] 。

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

id选择器QPushButton#okButton匹配所有QPushButton实例,其对象名称okButton
#include <QApplication>
#include <QPushButton>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QPushButton button;
    button.setObjectName("myButton");

    button.setStyleSheet("#myButton { color: blue; font-size: 16px; }");

    button.show();

    return a.exec();
}

派生类选择器QDialog QPushButton匹配所有作为QDialog的后代(子节点、孙节点等)的QPushButton实例。
子选择器QDialog > QPushButton匹配所有作为 QDialog 的直接子元素的 QPushButton 实例。

 子控件

        对于复杂小部件的样式设置,有必要访问小部件的子控件,例如QComboBox的下拉按钮或QSpinBox的上下箭头。选择器可能包含子控件,这使得能够将规则的应用限制在特定的小部件子控件上。例如:

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

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

         子控件始终相对于另一个元素(即参考元素)进行定位。此参考元素可以是小部件或另一个子控件。例如,默认情况下,“下拉列表”“QComboBox”的填充矩形的右上角。默认情况下,“下拉列表”位于“下拉列表”子控件的内容矩形的中心。有关用于设置小部件样式的子控件及其默认位置,请参阅下面的“可设置样式的小部件列表”

        可使用子控件原点属性更改要使用的原始矩形。例如,如果我们希望将下拉列表放置在QComboBox的边距矩形中,而不是默认的填充矩形中,我们可以指定:

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

        在 Margin 矩形内下拉列表的对齐方式使用子控件位置属性进行更改。

        宽度高度属性可用于控制子控件的大小。请注意,设置图像会隐式设置子控件的大小。

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

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

        绝对定位方案(位置:绝对)允许子控件的位置和大小相对于参考元素进行更改。

        一旦定位,它们就与小部件一样被对待,并且可以使用盒模型进行样式设置。

        请查看下面的子控件列表以获取受支持的子控件列表,以及自定义 QPushButton 的菜单指示器子控件以获取实际示例。

        注意:对于复杂的小部件,如QComboBoxQScrollBar,如果自定义了一个属性或子控件,那么所有其他属性或子控件也必须进行自定义。

伪状态

        选择器可能包含伪状态,这些伪状态表示根据小部件的状态限制规则的应用。伪状态出现在选择器的末尾,中间有一个冒号(:)。例如,当鼠标悬停在QPushButton 上时,以下规则适用:

QPushButton:hover { color: white }

        伪状态可以使用感叹号运算符进行取反。例如,当鼠标未悬停在QRadioButton 上时,以下规则适用:

QRadioButton:!hover { color: red }

        伪状态可以链接,在这种情况下意味着逻辑“与”。例如,以下规则适用于鼠标悬停在已选中的QCheckBox 上时:

QCheckBox:hover:checked { color: white }

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

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

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

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

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

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

        请查看下面的伪状态列表部分,以获取 Qt 小部件提供的伪状态列表。

冲突解决

        当多个样式规则指定相同的属性但具有不同的值时会产生冲突。考虑以下样式表:

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

        这两条规则都匹配名为 QPushButton 的实例,称为 okButton,并且对于 color 属性存在冲突。为了解决此冲突,我们必须考虑选择器的特异性。在上述示例中,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,可能会让人误以为QPushButtonQAbstractButton更具体。然而,对于样式表计算,所有类型选择器具有相同的特异性,最后出现的规则优先。换句话说,颜色被设置为gray对于所有QAbstractButton,包括QPushButton。如果我们确实希望QPushButton具有红色文本,我们总是可以重新排列规则。

一个选择器的特异性计算如下:

  1. 计算选择器(= a)中 ID 属性的数量
  2. 计算选择器(= b)中其他属性和伪类的数量
  3. 计算选择器(= c)中元素名称的数量
  4. 忽略伪元素(例如,子控件)。

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

级联

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

        当冲突出现时,小部件自身的样式表总是优先于任何继承的样式表,无论冲突规则的特异性如何。同样,父部件的样式表优先于祖父部件的样式表,等等。

        其中一个后果是,在小部件上设置样式规则会自动使其优先于在祖先小部件的样式表或QApplication样式表中指定的其他规则。考虑以下示例。首先,我们在QApplication上设置样式表:

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

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

        QPushButton 上的样式表强制 QPushButton(以及任何子部件)具有蓝色文本,尽管应用程序范围内的样式表提供了更具体的规则集。

        如果我们已经写了,结果会是一样的

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

        只是如果QPushButton有子元素(这不太可能),样式表对它们将没有影响。

        样式表级联是一个复杂的主题。请参考CSS2 规范以获取详细信息。请注意,Qt 目前尚未实现!important

继承

        在经典的 CSS 中,当一个项目的字体和颜色未明确设置时,它会自动从父项继承。在使用 Qt 样式表时,一个小部件不会自动从其父部件继承其字体和颜色设置。

        例如,考虑在QGroupBox 内的QPushButton :

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

        QPushButton 未设置明确的颜色。因此,它没有继承其父QGroupBox的颜色,而是采用了系统颜色。如果我们要为QGroupBox及其子元素设置颜色,可以这样写:

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

        相比之下,设置字体并使用QWidget::setFont() 和 QWidget::setPalette() 进行传播会传播到子部件。

命名空间中的小部件

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

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

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

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

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 声明的枚举,您应该通过名称引用其常量,即,不是它们的数值。

  • 24
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

春意盎然的三月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值