Qt样式表语法

来源:互联网 发布:形容好朋友的网络词 编辑:程序博客网 时间:2024/04/28 18:58
Qt样式表语法
Qt样式表术语和语法规则是几乎相同的跟HTML CSS。如果你已经了解了CSS,你可以很快的略过这个部分。




样式规则
样式表包括一系列样式规则。一个样式规则由一个选择器和一个声明构成。选择器可以指定那些widgets被这条规则影响;声明指定哪些widget属性应该被设置。例如 QPushButton{color:red}
在上面的样式规则,QPushButton是一个选择器并且{color:red}是一个声明.这条规则指定QPushButton机器子类应该使用红色作为它们的前景色。




Qt样式表是大小写不敏感的(color,Color,COLOR并且cOloR是一样的属性).唯一例外的是类名,对象名和Qt属性名是大小写敏感的。




几个选择其可以被指定一样的声明,使用逗号(,)来分离选择器.例如这条规则QPushButton,QLineEdit,QComboBox{color:red}是等同于下面的三条规则:
QPushButton{color:red} 
QLineEdit{color:red}
QComboBox{color:red}
一个样式规则的声明部分是一个属性:值对的列表,括在大括号里({})并且使用分好分隔。例如
QPushButton{color:red;backgroud-color:white}
可以看属性表部分由Qt widgets提供的属性列表。




选择器类型
到现在为止所有的例子使用了最简单的选择器类型。Qt样式表支持所有的在CSS2中定义的选择器。下面的表总结了最有用的选择器类型。
选择器         例子                             说明
通用选择器     *                              匹配所有的widgets
类型选择器    QPushButton                     匹配所有的QPushButton实例及其子类的实例
属性选择器    QPushButton[flat = "false"]     匹配QPushButton不是flat的实例。你可能使用这个选择器来
 测试任何支持QVariant::toString()的Qt属性。另外对类名称来说特殊的属性也被支持。这个选择器可能也被用来测试动态属性为了获取更多定制化信息使用动态属性时请参考Customzing Using Dynamic Properties.代替=你也可以使用~=来测试一个被给的QString是不是Qt的属性。
 警告:如果一个Qt属性值在Qt样式表被设置之后改变,它可能是必须强制一个样式表重新估计。一种办法是取得未被设置的样式表再次设置它。
类选择器    .QPushButton                      匹配所有的QPushButton的实例不包括它的子类等同于
 *[class ~="QPushButton"}
ID选择器    QPushButton#okButton              匹配所有对象名是okButton的QPushButton的实例
后代选择器  QDialog QPushButton               匹配所有QDialog后代的QPushButton的实例
子选择器    QDialog > QPushButton             匹配所有QDialog直接子类的QPushButton的实例




子控制器
对于设计复杂的widgets,它是必须的通过Widgets的子控制器,比如QComboBox的向下按钮或者QSpinBox的向下向上箭头。选择器可能包含子选择器,使它可以限制一个规则的应用到指定的widget子控制器。例如
QComboBox::drop-down{image:url(dropdown.png)}
上面的规则设计了所有的QComboBoxes的下拉按钮。尽管双冒号语法让人联想到CSS3的伪元素,但是Qt的子控制器从概念上是不同的并且有不同的级联语义。




子控制器总是被定位用另一个元素-一个参照元素。这个引用参考元素可以是widget或者另一个子控制器。例如一个QComboBox的::drop-down被默认放置在QComboBox填充矩形的右上角。::drop-down默认被放置在子控制器的内容矩形的中间。查看List of Stylable Widgets对子控制器来使用样式和它们的默认位置。




原始的矩形可以使用subcontrol-origin属性来改变。例如如果我们想要在QComboBox的边距矩形中放置下拉按钮替代默认的填充矩形我们可以指定
QComboBox{margin-right:20px;}
QComboBox::drop-down{ subcontrol-origin:margin;}
在边距矩形中的drop-down对齐方式可以用subcontrol-position属性来改变。
宽度和高度属性可以被用来控制子控制器的大小。注意设置一个图片隐含的设置了一个子控制器的大小。




子控制器的相对位置允许设置偏移相对于子控制器的原始位置。例如,当QComboBox的下拉按钮被按下,我们可能想实现一种按下的效果,为了实现这个我们可以指定:
QComboBox::down-arrow{ image:url(down_arraw.png);}
QComboBox::down-arrow:pressed{ position:relative;top:1px;left:1px;}
绝对位置(position:absolute)允许从引用的元素角度来改变子控制器的位置和大小
一旦被放置,它们将会被widgets同等对待并且被设计使用盒子模型。
查看List of Sub-Controls一个支持子控制器的列表并且 Customizing the QPushButton's Menu Indicator Sub-Control对于一个现实的例子。
注意:使用复杂的widgets比如QComboBox和QScrollBar如果一个属性或者子控制器被定制,所有的其他属性或者属性也必须被定制。




Pseudo-States
伪选择器 
选择器包含伪选择器表示限制应用规则的widgets的状态。伪选择器出现在子控制器的末尾使用冒号(:)分隔。例如,下面的规则应用当QPushButton上有鼠标的时候
QPushButton:hover{color:white}
伪选择器可以被否定使用感叹号,例如下面的规则应用当鼠标不在QRadioButton的上方时。
QRadioButton:!hover{color:red}
伪选择器可以被链起来使用and被隐含使用。例如下面的规则被应用当鼠标在checkBox上并且checkBox被选中时
QCheckBox:hover:checked{color:white}
否定伪选择器可能出现在伪选择器链。例如下面的规则被应用当鼠标在一个QPushButton上并且不被按下时。
QPushButton:hover:!pressed{color:blue}
如果需要,逻辑或也可以表达使用逗号
QCheckBox:hover,QCheckBox:checked{color:white}
伪选择器可以出现在和子控制器的组合里例如:
QComboBox:drop-down:hover{iamge:url(drop-down_bright.png)}
查看List of Pseudo-States部分有Qt widgets支持的伪选择器列表




冲突解决
当几个样式规则指定同样的属性不同的值冲突就会出现。思考下面的样式表
QPushButton#okButton{color:gray}
QPushButton{color:red}
上面的规则都匹配被称作okButton的QPushButton实例并且这有一个冲突对color属性来说。为了解决这个冲突,我们必须考虑到选择器的特殊性。在上面的例子中,QPushButton#okButton是更特殊的比QPushButton,因为它通常指一个对象而不是所有的类对象。
相似地,带有伪选择器的选择器似乎更特殊的比那些没有伪选择器的。因此,下面的指定一个QPushButton的样式表,Button的文本应该是白色的当鼠标移动到button上面时,其他情况是红色的
QPushButton:hover{color:white}
QPushButton{color:red}
这有一个技巧
QPushButton:hover{color:white}
QPushButton:enabled{color:red}
这两个选择器一样特殊时,因此如果当button可用时,鼠标覆盖在button上,第二条规则是优先的。假如在那样的情况下我们想要文本是白色我们可以重新排以下规则的顺序。
QPushButton:enabled{color:red}
QPushButton:hover{color:white}
同样地我们可以使得第一条规则更特殊
QPushButton:hover:enabled{color:white}
QPushButton:enabled{color:red}
同样的问题出现在类型选择器里,思考下面的例子
两条规则都应用于QPushButton的实例(因为QPushButton继承自QAbstractButton)并且这有一个冲突对color属性来说。因为QPushButton继承自QAbstractButton,假设QPushButton是比QAbstractButton更特殊的可能很诱导人。然而,对样式表评估来说,所有的类型选择器有一样的特殊性,并且最后出现的规则优选,换句话说,所有的QAbstractButtons的颜色被设置为gray包括QPushButtons。如果我们确实想要QPushButtons有红色的文本,我们可以更换规则的顺序。
为了决定一个规则的特殊性,Qt样式表效仿了CSS2。
    一个选择器的特殊性根据以下评估:
    1)在选择器中ID属性的数量(=a)
    2)在选择器中其他属性和伪选择器的数量(=b)
    3)在选择器中元素名称的数量(=c)
    4)忽略伪元素比如子控制器等等
级联Cascading
样式表可以被设置到QApplication和父窗口,以及子窗口上。一个任意的widget的有效样式表通过融合设置在widget祖先的样式表以及任何设置在QApplication上的样式表获得。




当冲突出现时,widget自己的样式表总是比其他任何继承的样式表优先。不考虑冲突规则的特殊性。同样的父窗口的样式表优先于祖父的等等。




这样设置一个样式规则在一个widget上自动地给出它优先在祖先的widget上的样式表或者QApplication的样式表。思考下面的例子,首先我们在QApplication上设置一个样式表。
qApp->setStyleSheet("QPushButton { color: white }");
然后我们在一个QPushButton对象上设置样式表。
myPushButton->setStyleSheet("* { color: blue }");
这个在QPushButton上的样式表强制QPushButton(和任何子类widget)有蓝色的文本,不管application-wide的样式表有多特殊。
如果我们这样写结果也是一样的
myPushButton->setStyleSheet("color: blue");
除了如果QPushButton有孩子之外,样式表是对它们没有影响的。
样式表级联是一个复杂的话题。参考CSS2 Specification为了具体的细节.请注意目前Qt还没有实现!important




继承Inheritance
在经典的CSS中,当一个项的字体和颜色没有被明确地设置,它将自动从派生自的父类获取。当使用Qt样式表时,一个widget将不会自动继承它的字体和颜色。
例如,思考在一个QGroupBox里的QPushButton.
qApp->setStyleSheet("QGroupBox { color: red; } ");
QPushButton没有明确设置一个颜色,因此替代它父类QGroupBox的颜色,它有一个系统颜色,如果我们想要设置一个颜色在QGroupBox和它的子类,我们可以写
qApp->setStyleSheet("QGroupBox, QGroupBox * { color: red; }");
与此相反,设置一个字体私用QWidget::setFont()和QWidget::setPalette()将传播到子widget.




在C++命名空间里的Widgets
类型选择器可以被用于一个特定类型的widgets例如
class MyPushButton : public QPushButton {
    // ...
}




// ...
qApp->setStyleSheet("MyPushButton { background: yellow; }");
Qt样式表使用widget的QObject::className()决定合适应用类型选择器。当定制的widget在命名空间里,QObject::className()返回<namspace>::<classname>.这是冲突的跟子类型语法。为了克服这个问题,当在命名空间里对widget使用类型选择器的时候,我们必须使用"--"代替"::"例如:
namespace ns {
    class MyPushButton : public QPushButton {
        // ...
    }
}




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




设置QObject属性
从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; }
如果属性引用了一个用Q_ENUMS声明的枚举,你应该引用它的常量通过名字而不是他们的数值。
0 0