打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
使用Qss设置窗体样式

本文主要是对官方文档的翻译。

一、Qss作用与规则

Qss(Qt style sheet)是一种样式文本规范,可以使用QApplication::setStyleSheet()来设置整个应用的样式或者使用QWidget::setStyleSheet()设置某个QWidget(包括其子类)窗体的样式。Qss具有级联属性,即假设在不同的级别设置了多个样式表,那么Qt将从所有设置的样式表中派生出有效的样式表。样式表可以让您执行所有类型的定制,这些定制仅使用QPalette是很难或不可能执行的。例如,你想要黄色背景作为强制字段,红色文本作为潜在的破坏性按钮,或者花哨的复选框,样式表就是答案。

样式规则由一个选择器(selector)和一个声明(declaration)组成。选择器指定哪些Widget受到该规则的影响;声明指定应该在Widget上设置哪些属性。例如:QPushButton { color: red } ,QPushButton是selector,{color:red}是declaration,这个规则指定QPushButton和其子类应该使用红色作为前景色(文本颜色)。样式规则中的申明部分是由一个{property:value}表组成的,例如:QPushButton { color: red; background-color: white }。当多个类型的Widget具有相同的{property:value}时也可以在selector部分使用逗号隔开,例如QPushButtonQLineEditQComboBox { color: red }。

二、selector类型

Qt样式表支持CSS2中定义的所有选择器。下表总结了常用的选择器类型。

selector示例解释

Universal Selector

*匹配所有Widget

Type Selector

QPushButton

匹配所有QPushButton组件和其子组件

Property Selector

QPushButton[flat="false"]

匹配所有非平面(flat="false")属性的QPushButton。这种过滤器中过滤的对象需要先设置QVariant支持的类型属性(setProperty(“flat”, “false”))。

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

Class Selector

.QPushButton

匹配QPushButton组件,但是不包含其子类。

ID Selector

QPushButton#okButton

匹配所有对象名是okButton的QPushButton控件

Descendant Selector

QDialog QPushButton

匹配QPushButton的所有实例,它们是QDialog的后代控件(子控件、孙控件等)。

Child Selector

QDialog > QPushButton

匹配QPushButton的所有实例,它们是QDialog的直接子对象。

三、Property类型

下表列出了Qt样式表支持的常用属性(所有属性见https://doc.qt.io/qt-5/stylesheet-reference.html)。可以给属性赋哪些值取决于属性的类型。除非另有说明,以下属性适用于所有小部件。标记有星号*的属性是特定于Qt的,在CSS2或CSS3中没有相同的属性。

Proprty类型解释
alternate-background-colorBrush

alternate-background-color主要用于 QAbstractItemView子类,用来设置视图文本的交替背景色(需要设置视图的交替背景色属性)。例如:

  1. QTreeView {
  2. alternate-background-color: blue;
  3. background: yellow;
  4. }
backgroundBackground

设置窗体背景的简写,包括设置background-colorbackground-imagebackground-repeatbackground-position等.例如:

  1. QTextWdit {background:red};
  2. QFrame {background:url(:/img/first.jpg)};
background-colorBrush设置窗体的背景颜色。例如:QLabel { background-color: yellow } QLineEdit { background-color: rgb(255, 0, 0) }
background-imageUrl设置窗体的背景图片,图像的半透明部分让背景色透过。例:QFrame { background-image: url(:/images/hydro.png) }
background-repeatRepeat

设置背景图像是否重复填充背景原点矩形,以及如何重复填充。默认是在两个方向上重复(repeat)。

  1. QFrame {
  2. background: white url(:/images/ring.png);
  3. background-repeat: repeat-y;
  4. background-position: left;
  5. }
background-positionAlignment

背景原点矩形内背景图像的对齐。默认对齐方式为左上角。​​​​​​

  1. QFrame {
  2. background: url(:/images/footer.png);
  3. background-position: bottom left;
  4. }
background-attachmentAttachment设置QAbstractScrollArea中的背景图像相对于视口是滚动还是固定。默认情况下,背景图像会随着视口滚动。
background-clipOrigin设置背景色和背景图像被剪切填充背景矩形的方式。
background-originOrigin设置窗体的背景矩形,与背景位置和背景图像一起使用。
borderBorder设置窗体的边框属性,包括border-colorborder-style和border-width。也可以使用border-top、border-left等独立设置边框的每一条边的样式。例如:QLineEdit { border: 1px solid white } 、QLineEdit { border-right: 1px solid white }
border-colorBox Colors

设置边框的颜色样式,同样可以使用border-top-color、border-bottom-color等独立设置边框的每一条边的颜色样式。例如:

QLineEdit { border-color: white } 、QLineEdit { border-right-color: red }

border-imageBorder Image使用图片来填充边框。图像被切成九个部分(top left, top center, top right, center left, center, center right, bottom left, bottom center, and bottom right),并在必要时适当拉伸。
border-radiusRadius

设置矩形四个角的弧度,还可以使用border-top-left-radiusborder-top-right-radiusborder-bottom-right-radius, and border-bottom-left-radius来指定某一个角的弧度。例如:

QLineEdit { border-radius: 4px; }

border-styleBorder Style设置边框线的类型,还可以使用border-top-styleborder-right-style等来指定任意线的类型。QLineEdit { border-style: solid;}
border-widthBox Lengths设置边框线的宽度,同样可以使用border-top-widthborder-right-width等设置特定线的宽度。QLineEdit { border-width: 1px;}
bottomLength设置控件中子控件(如ComboBox的下拉按钮)的位置。若位置是相对的(默认)则将子控件向上移动指定的偏移量;若位置的绝对的,则指定子控件底部与父控件底部的距离。例如:QSpinBox::down-button { bottom: 2px }。同样可以使用left、top、right等设置子控件与父控件的其他边距。使用height设置子控件高度。
colorBrush设置文本的颜色,例如:QPushButton { color: red }
fontFont设置文字属性,包括font-family(字体)font-size(大小)font-style(倾斜)和 font-weight(加粗)。例如:QCheckBox { font: bold italic large "Times New Roman" }
gridline-color*Color设置QTableView中网格线的颜色。例如:* { gridline-color: gray }
iconUrl+设置具有图标控件的图标,目前具有此属性的控件只有QPushButton。
icon-sizeLength设置图标的长和宽。
image*Url+在子控件的内容矩形中绘制的图像。例如:QSpinBox::down-button { image: url(:/images/spindown.png) }
lineedit-password-character*Number设置QLineEdit中显示的字符,可使用Unicode的字符编码指定。例如* { lineedit-password-character: 9679 },表示使用Unicode中9679号字符显示。
lineedit-password-mask-delay*Number在lineedit-password-character应用于可见字符之前,QLineEdit密码掩码延迟(以毫秒为单位)。例如:* { lineedit-password-mask-delay: 1000 }
marginBox Lengths设置窗体与其他窗体的边缘距离,具体可使用margin-topmargin-rightmargin-bottom, 和 margin-left来指定。例如:QLineEdit { margin: 2px }
paddingBox Lengths

设置窗体与内部子窗体之间的边距,同样可使用padding-toppadding-rightpadding-bottom 和 padding-left来特定指定。例如:QLineEdit { padding: 3px }

spacing*Length设置内部子窗体之间的边距。例如:QMenuBar { spacing: 10 }
text-alignAlignment设置字体对齐方式。QPushButton {    text-align: left;}

以上只是简单介绍一些常用的属性设置,具体的各种属性该怎样设置可以查看每个属性的类型,官方文档给出了很详细的每种属性设置的方式以及意义。

四、子控件

Qss除了对常用控件、窗体的样式进行设置,还可以对其子控件(如QComboBox的下拉按钮、QSpinBox的上下按钮等)的位置,填充图片等属性进行设置。此时可以使用控件名::子控件名来表示selector。例如:QComboBox::drop-down { image: url(dropdown.png) }用来设置QComboBox的下拉按钮的图片。更多的子控件名称如下表:

子控件解释
::add-lineQScrollBar添加一行的按钮。
::add-page在句柄(滑块)和QScrollBar的附加行之间的区域。
::branchQTreeView的分支指示器。
::chunkQProgressBar的进度块。
::close-buttonQDockWidget的关闭按钮或QTabBar的选项卡
::cornerQAbstractScrollArea中两个滚动条之间的角
::down-arrowQComboBox、QHeaderView(排序指示器)、QScrollBar或QSpinBox的向下箭头。
::down-buttonQScrollBar或QSpinBox的向下按钮。
::drop-downQComboBox的下拉按钮。
::float-buttonQDockWidget的浮动按钮
::grooveQSlider的凹槽。
::indicatorQAbstractItemView、QCheckBox、QRadioButton、可检查QMenu项或可检查QGroupBox的指示器。
::handleQScrollBar、QSplitter或QSlider的句柄(滑块)。
::iconQAbstractItemView或QMenu的图标。
::itemQAbstractItemView、QMenuBar、QMenu或QStatusBar的一个条目。
::left-arrowQScrollBar的左箭头。
::left-cornerQTabWidget的左上角。例如,此控件可用于控制QTabWidget中左侧窗口小部件的位置。
::menu-arrow带有菜单的QToolButton的箭头。
::menu-buttonQToolButton的菜单按钮。
::menu-indicatorQPushButton的菜单指示器。
::right-arrowQMenu或QScrollBar的右箭头。
::paneQTabWidget的窗格(框架)。
::right-cornerQTabWidget的右角。例如,此控件可用于控制QTabWidget中右下角小部件的位置。
::scrollerQMenu或QTabBar的滚动条。
::sectionQHeaderView的部分。
::separatorQMenu或qmain窗口中的分隔符。
::sub-line删除一行QScrollBar的按钮。
::sub-page在句柄(滑块)和QScrollBar的子行之间的区域。
::tabQTabBar或QToolBox的选项卡。
::tab-barQTabWidget的选项卡栏。此子控件的存在只是为了控制QTabWidget中QTabBar的位置。使用::tab子控件样式化选项卡。
::tearQTabBar的撕裂指示器。
::tearoffQMenu的撕下指示器。
::textQAbstractItemView的文本。
::titleQGroupBox或QDockWidget的标题。
::up-arrowQHeaderView(排序指示器)、QScrollBar或QSpinBox的向上箭头。
::up-buttonQSpinBox的向上按钮。

五、伪状态

Qt中有的控件会有许多状态,有时需要对不同状态进行区分(例如按钮的选中、按下等状态的区分),需要为不同的状态设置不同的样式。此时使用 控件名:状态名 表示selector。例如:QPushButton:hover { color: white }表示设置鼠标放在按钮上时按钮字体颜色。更多的状态名称见下表:

伪状态解释
:active窗体为活动窗体时的状态
:adjoins-item当一个QTreeView的::branch与一个项目相邻时,该状态被设置。
:alternate当QAbstractItemView::alternatingRowColors()被设置为true时,绘制QAbstractItemView的每一行时都会设置此状态。
:bottom控件位于底部。例如,QTabBar的标签位于底部。
:checked选中该项。例如,QAbstractButton的选中状态。
:closable项目可以关闭。例如,QDockWidget打开了QDockWidget:: dockwidgetcloseable特性。
:closed项目处于关闭状态。例如,QTreeView中的一个非展开项
:default该项目是默认的。例如,一个默认的QPushButton或QMenu中的一个默认动作。
:disabled该项目被禁用。
:editableQComboBox是可编辑的。
:edit-focus项目有编辑焦点(见QStyle::State_HasEditFocus)。此状态仅适用于Qt扩展应用程序。
:enabled启用该项。
:exclusive该项是独占项组的一部分。例如,独占QActionGroup中的菜单项。
:first该项目是(列表中的)第一项。例如,QTabBar中的第一个选项卡。
:flat项目是扁平的。例如,一个平面的QPushButton。
:floatable项目可以浮动。例如,QDockWidget启用了QDockWidget:: dockwidgetfloatatable特性。
:focus项目有输入焦点。
:has-children该项目有子项目。例如,QTreeView中的一项有子项。
:has-siblings该项目有兄弟项。例如,QTreeView中的一个条目。
:horizontal项目具有水平方向
:hover鼠标悬停在项目上。
:indeterminate项目处于不确定状态。例如,QCheckBox或QRadioButton被部分选中。
:last这个项目是(列表中)最后一个项目。例如,QTabBar中的最后一个选项卡。
:left项目位于左侧。例如,QTabBar的选项卡位于左侧。
:maximized项目被最大化。例如,最大化的QMdiSubWindow。
:middle项目在(列表中)中间。例如,一个不在QTabBar开始或结束的选项卡。
:minimized项目被最小化了。例如,最小化的QMdiSubWindow。
:movable项目可以四处移动。例如,QDockWidget启用了QDockWidget::DockWidgetMovable特性。
:no-frame该项目没有框架。例如,一个无框架的QSpinBox或QLineEdit。
:non-exclusive项是非排他项组的一部分。例如,非排他的QActionGroup中的菜单项。
:off对于可以切换的项,这适用于处于“关闭”状态的项。
:on对于可以切换的项,这适用于处于“on”状态的小部件。
:only-one该项目是唯一的(在列表中)。例如,QTabBar中的一个单独的标签。
:open项目处于打开状态。例如,一个在QTreeView中展开的项目,或者一个带有打开菜单的QComboBox或QPushButton。
:next-selected选择下一个项目(在列表中)。例如,QTabBar选中的选项卡就在该项的旁边。
:pressed项目正在使用鼠标按下。
:previous-selected选中前一个项目(在列表中)。例如,QTabBar中紧邻所选选项卡的选项卡。
:read-only该项被标记为只读或不可编辑。例如,只读QLineEdit或不可编辑的QComboBox。
:right项目位于右侧。例如,QTabBar的选项卡位于右侧。
:selected项目被选中。例如,QTabBar中选定的选项卡或QMenu中选定的项。
:top项目位于顶部。例如,QTabBar的标签位于顶部。
:unchecked未选中该项。
:vertical项目具有垂直方向。
:window小部件是一个窗口(即顶层小部件)

六、冲突处理机制

当多个样式规则用不同的值指定相同的属性时,考虑以下样式表:QPushButton#okButton { color: gray }    QPushButton { color: red } 。这两个规则都匹配名为okButton的QPushButton实例,并且对于color属性存在冲突。为了解决这个冲突,我们必须考虑选择器的特殊性。在上面的例子中,QPushButton#okButton被认为比QPushButton更具体,因为它(通常)引用一个对象,而不是一个类的所有实例。

所以当多个样式规则产生冲突时,系统会选择更具有针对性(特异性)的样式规则进行使用。而为了确定规则的特异性,Qt样式表遵循CSS2规范:

选择器的特异性计算如下:
              统计选择器中ID属性的数量(= a)
              计算选择器中其他属性和伪类的数量(= b)
              计算选择器中元素名称(如LI、OL等元素名称)的数量(= c)

然后根据a*100+b*10+c计算出相应规则的特异性值。特异性值越大匹配性越好。

例如:

  1. * {} /* a=0 b=0 c=0 -> specificity = 0 */
  2. LI {} /* a=0 b=0 c=1 -> specificity = 1 */
  3. UL LI {} /* a=0 b=0 c=2 -> specificity = 2 */
  4. UL OL+LI {} /* a=0 b=0 c=3 -> specificity = 3 */
  5. H1 + *[REL=up]{} /* a=0 b=1 c=1 -> specificity = 11 */
  6. UL OL LI.red {} /* a=0 b=1 c=3 -> specificity = 13 */
  7. LI.red.level {} /* a=0 b=2 c=1 -> specificity = 21 */
  8. #x34y {} /* a=1 b=0 c=0 -> specificity = 100 */

七、示例

改示例主要是对Qt自带的Style sheet示例的修改。

  1. //.h
  2. #ifndef WIDGET_H
  3. #define WIDGET_H

  4. #include <QMainWindow>
  5. #include <QApplication>

  6. class Widget : public QMainWindow
  7. {
  8. Q_OBJECT

  9. public:
  10. Widget(QMainWindow *parent = nullptr);
  11. ~Widget();
  12. };
  13. #endif // WIDGET_H


  14. //.cpp
  15. #include "widget.h"
  16. #include <QFrame>
  17. #include <QLabel>
  18. #include <QComboBox>
  19. #include <QSpinBox>
  20. #include <QLineEdit>
  21. #include <QTextEdit>
  22. #include <QCheckBox>
  23. #include <QRadioButton>
  24. #include <QHBoxLayout>
  25. #include <QGridLayout>
  26. #include <QGroupBox>
  27. #include <QStringList>
  28. #include <QDialogButtonBox>
  29. #include <QFile>
  30. #include <QMessageBox>

  31. Widget::Widget(QMainWindow *parent)
  32. : QMainWindow(parent)
  33. {


  34. QLabel *label1 = new QLabel("姓名:");
  35. label1->setProperty("class","mandatory");
  36. QComboBox *cmb1 = new QComboBox();
  37. cmb1->setObjectName("name");
  38. cmb1->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Fixed); //默认为双Preferred

  39. QLabel *label2 = new QLabel("性别:");
  40. QRadioButton *rbtn1 = new QRadioButton("男");
  41. QRadioButton *rbtn2 = new QRadioButton("女");
  42. QHBoxLayout *hlayout1 = new QHBoxLayout();
  43. hlayout1->addWidget(rbtn1);
  44. hlayout1->addWidget(rbtn2);
  45. hlayout1->addStretch(1);
  46. QGroupBox *groupBox = new QGroupBox();
  47. groupBox->setLayout(hlayout1);

  48. QLabel *label3 = new QLabel(" 年龄:");
  49. QSpinBox *spinBox1 = new QSpinBox();
  50. spinBox1->setValue(22);
  51. spinBox1->setRange(18,45);
  52. spinBox1->setSingleStep(1);
  53. QHBoxLayout *hlayout2 = new QHBoxLayout();
  54. hlayout2->addWidget(spinBox1);
  55. hlayout2->addStretch(1);

  56. QLabel *label4 = new QLabel("密码:");
  57. QLineEdit *lineEdit1 =new QLineEdit("Password");
  58. lineEdit1->setEchoMode(QLineEdit::Password);

  59. QLabel *label5 = new QLabel(" 国家:");
  60. QComboBox *cmb2 = new QComboBox();
  61. QStringList str;
  62. str<<"中国"<<"埃及"<<"法国"<<"德国"<<"意大利"<<"印度"<<"挪威"<<"巴基斯坦";
  63. cmb2->addItems(str);
  64. cmb2->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Fixed);

  65. QLabel *label6 = new QLabel("职业:");
  66. QTextEdit *textEdit1 = new QTextEdit("开发者");
  67. textEdit1->append("学生");
  68. textEdit1->append("创业者");
  69. textEdit1->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);

  70. QCheckBox *checkBox = new QCheckBox("我接受这些条款和条件!");

  71. QDialogButtonBox *dialogBtnBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);

  72. QGridLayout *glayout = new QGridLayout();
  73. glayout->addWidget(label1,0,0);
  74. glayout->addWidget(cmb1,0,1);
  75. glayout->addWidget(label2,1,0);
  76. glayout->addWidget(groupBox,1,1);
  77. glayout->addWidget(label3,2,0);
  78. glayout->addLayout(hlayout2,2,1);
  79. glayout->addWidget(label4,3,0);
  80. glayout->addWidget(lineEdit1,3,1);
  81. glayout->addWidget(label5,4,0);
  82. glayout->addWidget(cmb2,4,1);
  83. glayout->addWidget(label6,5,0);
  84. glayout->addWidget(textEdit1,5,1);
  85. glayout->addWidget(checkBox,6,0,1,2);
  86. glayout->addWidget(dialogBtnBox,7,0,1,2);
  87. glayout->setSizeConstraint(QLayout::SetDefaultConstraint);

  88. QString dirPath = QApplication::applicationDirPath();
  89. //QString fileName = dirPath+"/coffee.qss";

  90. QString fileName = "../qss/qss/coffee.qss";
  91. QFile qssFile(fileName);
  92. if(!qssFile.open(QFile::ReadOnly))
  93. {

  94. QMessageBox::warning(this,"打开文件失败",fileName+"打开失败");
  95. exit(1);
  96. }
  97. QString qssString = qssFile.readAll();
  98. this->setStyleSheet(qssString);

  99. QFrame *mframe = new QFrame();
  100. mframe->setLayout(glayout);
  101. this->setCentralWidget(mframe);
  102. }

  103. Widget::~Widget()
  104. {
  105. }

.qss文件

  1. Widget {
  2. background-color: beige;
  3. }


  4. /* Nice Windows-XP-style password character. */
  5. QLineEdit[echoMode="2"] {
  6. lineedit-password-character: 9679;
  7. }

  8. /* We provide a min-width and min-height for push buttons
  9. so that they look elegant regardless of the width of the text. */
  10. QPushButton {
  11. background-color: palegoldenrod;
  12. border-width: 2px;
  13. border-color: darkkhaki;
  14. border-style: solid;
  15. border-radius: 5;
  16. padding: 3px;
  17. min-width: 9ex;
  18. min-height: 2.5ex;
  19. }

  20. QPushButton:hover {
  21. background-color: khaki;
  22. }

  23. /* Increase the padding, so the text is shifted when the button is
  24. pressed. */
  25. QPushButton:pressed {
  26. padding-left: 5px;
  27. padding-top: 5px;
  28. background-color: #d0d67c;
  29. }

  30. QLabel, QAbstractButton {
  31. font: bold;
  32. }

  33. /* Mark mandatory fields with a brownish color. */
  34. .mandatory {
  35. color: brown;
  36. }

  37. /* Bold text on status bar looks awful. */
  38. QStatusBar QLabel {
  39. font: normal;
  40. }

  41. QStatusBar::item {
  42. border-width: 1;
  43. border-color: darkkhaki;
  44. border-style: solid;
  45. border-radius: 2;
  46. }

  47. QComboBox, QLineEdit, QSpinBox, QTextEdit, QListView {
  48. background-color: cornsilk;
  49. selection-color: #0a214c;
  50. selection-background-color: #C19A6B;
  51. }

  52. QComboBox::drop-down#name{
  53. image:url(:/res/drop_down.jpg);
  54. }

  55. QListView {
  56. show-decoration-selected: 1;
  57. }

  58. QListView::item:hover {
  59. background-color: wheat;
  60. }

  61. /* We reserve 1 pixel space in padding. When we get the focus,
  62. we kill the padding and enlarge the border. This makes the items
  63. glow. */
  64. QFrame{
  65. /*background-color: beige;*/
  66. margin:10px;
  67. }

  68. QLineEdit, QFrame {
  69. border-width: 2px;
  70. padding: 1px;
  71. border-style: solid;
  72. border-color: darkkhaki;
  73. border-radius: 5px;
  74. }

  75. /* As mentioned above, eliminate the padding and increase the border. */
  76. QLineEdit:focus, QFrame:focus {
  77. border-width: 3px;
  78. padding: 0px;
  79. }

  80. /* A QLabel is a QFrame ... */
  81. QLabel {
  82. border: none;
  83. padding: 0;
  84. background: none;
  85. }

  86. /* A QToolTip is a QLabel ... */
  87. QToolTip {
  88. border: 2px solid darkkhaki;
  89. padding: 5px;
  90. border-radius: 3px;
  91. opacity: 200;
  92. }

  93. /* Nice to have the background color change when hovered. */
  94. QRadioButton:hover, QCheckBox:hover {
  95. background-color: wheat;
  96. }

  97. /* Force the dialog's buttons to follow the Windows guidelines. */
  98. QDialogButtonBox {
  99. button-layout: 0;
  100. }

效果图:

转自:使用Qss设置窗体样式_cloud_yq的博客-CSDN博客_qss设置样式 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
QSS-pyqt样式表
漂亮的Qt控件 QSS代码例子
Qt StyleSheet样式表实例(转)
qt5中在QMainWidget中创建菜单栏等一系列控件
PyQt5之布局管理
setStyleSheet来设置图形界面的外观
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服