Qt 样式表示例
现在我们来看几个示例,以便开始使用 Qt 样式表。
样式表用法
自定义前景色和背景色
让我们先将黄色设置为应用程序中所有QLineEdits 的背景色。这可以这样实现:
qApp->setStyleSheet("QLineEdit { background-color: yellow }");
如果我们希望该属性只应用于作为特定对话框的子对话框(或孙对话框或曾孙对话框)的QLineEdit,我们宁愿这样做:
myDialog->setStyleSheet("QLineEdit { background-color: yellow }");
如果我们希望该属性只应用于一个特定的QLineEdit ,我们可以使用QObject::setObjectName() 给它命名,并使用 ID 选择器来引用它:
myDialog->setStyleSheet("QLineEdit#nameEdit { background-color: yellow }");
或者,我们可以直接在QLineEdit 上设置background-color属性,省略选择器:
nameEdit->setStyleSheet("background-color: yellow");
为了确保良好的对比度,我们还应该为文本指定合适的颜色:
nameEdit->setStyleSheet("color: blue; background-color: yellow");
也可以更改选定文本的颜色:
nameEdit->setStyleSheet("color: blue;" "background-color: yellow;" "selection-color: yellow;" "selection-background-color: blue;");
使用动态属性进行自定义
在很多情况下,我们需要显示一个带有必填字段的表单。为了向用户表明该字段是必填字段,一种有效(尽管美观上有问题)的解决方案是使用黄色作为这些字段的背景色。事实证明,使用 Qt 样式表很容易实现这一点。首先,我们将使用以下应用程序范围的样式表:
*[mandatoryField="true"] { background-color: yellow }
这意味着每个mandatoryField
Qt 属性设置为 true 的 widget 都会有黄色背景。
然后,对于每个必填字段 widget,我们只需即时创建一个mandatoryField
属性并将其设置为 true。例如
QLineEdit *nameEdit = new QLineEdit(this); nameEdit->setProperty("mandatoryField", true); QLineEdit *emailEdit = new QLineEdit(this); emailEdit->setProperty("mandatoryField", true); QSpinBox *ageSpinBox = new QSpinBox(this); ageSpinBox->setProperty("mandatoryField", true);
使用方框模型自定义 QPushButton
这次,我们将展示如何创建一个红色的QPushButton 。这个QPushButton 大概会与一段极具破坏性的代码相连。
首先,我们很想使用这个样式表:
QPushButton#evilButton { background-color: red }
然而,结果却是一个枯燥乏味、没有边框的扁平按钮:
事情是这样的:
- 我们提出的要求无法仅通过本地样式来满足(例如,Windows Vista 主题引擎不允许我们指定按钮的背景颜色)。
- 因此,我们使用样式表来渲染按钮。
- 我们没有为border-width和border-style 指定任何值,因此默认情况下,我们将获得 0 像素宽的边框样式
none
。
让我们通过指定边框来改善这种情况:
QPushButton#evilButton { background-color: red; border-style: outset; border-width: 2px; border-color: beige; }
情况看起来已经好多了。但是按钮看起来有点拥挤。让我们使用padding 来指定边框和文本之间的间距。此外,我们还将执行最小宽度、圆角并指定更大的字体,以使按钮看起来更美观:
QPushButton#evilButton { background-color: red; border-style: outset; border-width: 2px; border-radius: 10px; border-color: beige; font: bold 14px; min-width: 10em; padding: 6px; }
剩下的唯一问题就是按下按钮时按钮没有反应。我们可以通过指定略微不同的背景颜色和使用不同的边框样式来解决这个问题。
QPushButton#evilButton { background-color: red; border-style: outset; border-width: 2px; border-radius: 10px; border-color: beige; font: bold 14px; min-width: 10em; padding: 6px; } QPushButton#evilButton:pressed { background-color: rgb(224, 0, 0); border-style: inset; }
自定义 QPushButton 的菜单指示子控件
子控件允许访问部件的子元素。例如,与菜单(使用QPushButton::setMenu()) 关联的QPushButton 就有一个菜单指示器。让我们自定义红色按钮的菜单指示器:
QPushButton#evilButton::menu-indicator { image: url(myindicator.png); }
默认情况下,菜单指示器位于填充矩形的右下角。我们可以通过指定子控件位置(subcontrol-position)和子控件原点(subcontrol-origin)来改变菜单指示器的位置。我们还可以使用top和left将指示器移动几个像素。例如
QPushButton::menu-indicator { image: url(myindicator.png); subcontrol-position: right center; subcontrol-origin: padding; left: -2px; }
这将myindicator.png
定位到QPushButton 的填充矩形(更多信息请参阅子控件-原点)的右侧中心。
复杂选择器示例
由于红色似乎是我们最喜欢的颜色,因此让我们通过设置以下应用程序范围的样式表,将QLineEdit 中的文本设置为红色:
QLineEdit { color: red }
不过,我们希望通过使QLineEdit 显示为灰色,来直观地表明它是只读的:
在某一时刻,我们的设计团队要求注册表单中的所有QLineEdit(object name registrationDialog
)都是棕色的:
QLineEdit { color: red } QLineEdit[readOnly="true"] { color: gray } #registrationDialog QLineEdit { color: brown }
几次用户界面设计会议之后,我们决定所有的QDialog都应该使用棕色的QLineEdit:
QLineEdit { color: red } QLineEdit[readOnly="true"] { color: gray } QDialog QLineEdit { color: brown }
小测验:如果我们在QDialog 中设置了只读QLineEdit ,会发生什么情况?[提示:上面的冲突解决部分解释了类似情况下会发生的情况]。
自定义特定部件
本节提供了使用样式表自定义特定部件的示例。
自定义 QAbstractScrollArea
任何QAbstractScrollArea (项目视图、QTextEdit 和QTextBrowser )的背景都可以使用背景属性来设置。例如,设置一个随滚动条滚动的背景图片:
QTextEdit, QListView { background-color: white; background-image: url(draft.png); background-attachment: scroll; }
如果背景图片与视口保持一致,则背景图片将随滚动条滚动:
QTextEdit, QListView { background-color: white; background-image: url(draft.png); background-attachment: fixed; }
自定义 QCheckBox
QCheckBox 的样式与QRadioButton 的样式几乎相同。主要区别在于三态QCheckBox 具有不确定的状态。
QCheckBox { spacing: 5px; } QCheckBox::indicator { width: 13px; height: 13px; } QCheckBox::indicator:unchecked { image: url(:/images/checkbox_unchecked.png); } QCheckBox::indicator:unchecked:hover { image: url(:/images/checkbox_unchecked_hover.png); } QCheckBox::indicator:unchecked:pressed { image: url(:/images/checkbox_unchecked_pressed.png); } QCheckBox::indicator:checked { image: url(:/images/checkbox_checked.png); } QCheckBox::indicator:checked:hover { image: url(:/images/checkbox_checked_hover.png); } QCheckBox::indicator:checked:pressed { image: url(:/images/checkbox_checked_pressed.png); } QCheckBox::indicator:indeterminate:hover { image: url(:/images/checkbox_indeterminate_hover.png); } QCheckBox::indicator:indeterminate:pressed { image: url(:/images/checkbox_indeterminate_pressed.png); }
自定义 QComboBox
我们将举例说明QComboBox 的下拉按钮与组合框框架 "合并 "的情况。
QComboBox { border: 1px solid gray; border-radius: 3px; padding: 1px 18px 1px 3px; min-width: 6em; } QComboBox:editable { background: white; } QComboBox:!editable, QComboBox::drop-down:editable { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #E1E1E1, stop: 0.4 #DDDDDD, stop: 0.5 #D8D8D8, stop: 1.0 #D3D3D3); } /* QComboBox gets the "on" state when the popup is open */ QComboBox:!editable:on, QComboBox::drop-down:editable:on { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #D3D3D3, stop: 0.4 #D8D8D8, stop: 0.5 #DDDDDD, stop: 1.0 #E1E1E1); } QComboBox:on { /* shift the text when the popup opens */ padding-top: 3px; padding-left: 4px; } QComboBox::drop-down { subcontrol-origin: padding; subcontrol-position: top right; width: 15px; border-left-width: 1px; border-left-color: darkgray; border-left-style: solid; /* just a single line */ border-top-right-radius: 3px; /* same radius as the QComboBox */ border-bottom-right-radius: 3px; } QComboBox::down-arrow { image: url(/usr/share/icons/crystalsvg/16x16/actions/1downarrow.png); } QComboBox::down-arrow:on { /* shift the arrow when popup is open */ top: 1px; left: 1px; }
QComboBox 的弹出窗口是QAbstractItemView ,并使用后代选择器进行了样式设置:
QComboBox QAbstractItemView { border: 2px solid darkgray; selection-background-color: lightgray; }
自定义 QDockWidget
QDockWidget 的标题栏和按钮可按以下方式自定义:
QDockWidget { border: 1px solid lightgray; titlebar-close-icon: url(close.png); titlebar-normal-icon: url(undock.png); } QDockWidget::title { text-align: left; /* align the text to the left */ background: lightgray; padding-left: 5px; } QDockWidget::close-button, QDockWidget::float-button { border: 1px solid transparent; background: darkgray; padding: 0px; } QDockWidget::close-button:hover, QDockWidget::float-button:hover { background: gray; } QDockWidget::close-button:pressed, QDockWidget::float-button:pressed { padding: 1px -1px -1px 1px; }
如果希望将停靠窗口小部件的按钮移到左边,可以使用下面的样式表:
QDockWidget { border: 1px solid lightgray; titlebar-close-icon: url(close.png); titlebar-normal-icon: url(float.png); } QDockWidget::title { text-align: left; background: lightgray; padding-left: 35px; } QDockWidget::close-button, QDockWidget::float-button { background: darkgray; padding: 0px; icon-size: 14px; /* maximum icon size */ } QDockWidget::close-button:hover, QDockWidget::float-button:hover { background: gray; } QDockWidget::close-button:pressed, QDockWidget::float-button:pressed { padding: 1px -1px -1px 1px; } QDockWidget::close-button { subcontrol-position: top left; subcontrol-origin: margin; position: absolute; top: 0px; left: 0px; bottom: 0px; width: 14px; } QDockWidget::float-button { subcontrol-position: top left; subcontrol-origin: margin; position: absolute; top: 0px; left: 16px; bottom: 0px; width: 14px; }
注: 要自定义QDockWidget 的分隔符(调整大小句柄),请使用 QMainWindow::separator。
自定义 QFrame
QFrame 使用框模型(The Box Model)设计样式。
QFrame, QLabel, QToolTip { border: 2px solid green; border-radius: 4px; padding: 2px; background-image: url(images/welcome.png); }
自定义 QGroupBox
让我们来看一个将QGroupBox 的标题移至中心的示例。
QGroupBox { background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #E0E0E0, stop: 1 #FFFFFF); border: 2px solid gray; border-radius: 5px; margin-top: 1ex; /* leave space at the top for the title */ } QGroupBox::title { subcontrol-origin: margin; subcontrol-position: top center; /* position at the top center */ padding: 0 3px; background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #FF0ECE, stop: 1 #FFFFFF); }
对于可选中的QGroupBox ,请使用 {#indicator-sub}{::indicator} 子控件,并将其样式设置为与QCheckBox 完全相同(即)
QGroupBox::indicator { width: 13px; height: 13px; } QGroupBox::indicator:unchecked { image: url(:/images/checkbox_unchecked.png); } /* proceed with styling just like QCheckBox */
自定义 QHeaderView
QHeaderView 定制如下:
QHeaderView::section { background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #616161, stop: 0.5 #505050, stop: 0.6 #434343, stop:1 #656565); color: white; padding-left: 4px; border: 1px solid #6c6c6c; } QHeaderView::section:checked { background-color: red; } /* style the sort indicator */ QHeaderView::down-arrow { image: url(down_arrow.png); } QHeaderView::up-arrow { image: url(up_arrow.png); }
自定义 QLineEdit
QLineEdit 的边框样式是使用方框模型设计的。要创建带圆角的行编辑器,我们可以设置
QLineEdit { border: 2px solid gray; border-radius: 10px; padding: 0 8px; background: yellow; selection-background-color: darkgray; }
可以使用QLineEdit::Password echo 模式设置行编辑器的密码字符:
QLineEdit[echoMode="2"] { lineedit-password-character: 9679; }
只读QLineEdit 的背景可以如下修改:
QLineEdit:read-only { background: lightblue; }
自定义 QListView
可以使用以下样式表自定义交替行的背景颜色:
QListView { alternate-background-color: yellow; }
要在项目悬停时提供特殊背景,我们可以使用::item子控件。例如
QListView { show-decoration-selected: 1; /* make the selection span the entire width of the view */ } QListView::item:alternate { background: #EEEEEE; } QListView::item:selected { border: 1px solid #6a6ea9; } QListView::item:selected:!active { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ABAFE5, stop: 1 #8588B2); } QListView::item:selected:active { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #6a6ea9, stop: 1 #888dd9); } QListView::item:hover { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #FAFBFE, stop: 1 #DCDEF1); }
自定义 QMainWindow
QMainWindow 的分隔符的样式如下:
QMainWindow::separator { background: yellow; width: 10px; /* when vertical */ height: 10px; /* when horizontal */ } QMainWindow::separator:hover { background: red; }
自定义 QMenu
QMenu 的单个项目可使用 "item "子控件设置样式,如下所示:
QMenu { background-color: #ABABAB; /* sets background of the menu */ border: 1px solid black; } QMenu::item { /* sets background of menu item. set this to something non-transparent if you want menu color and menu item color to be different */ background-color: transparent; } QMenu::item:selected { /* when user selects item using mouse or keyboard */ background-color: #654321; }
要进行更高级的定制,可使用样式表,如下所示:
QMenu { background-color: white; margin: 2px; /* some spacing around the menu */ } QMenu::item { padding: 2px 25px 2px 20px; border: 1px solid transparent; /* reserve space for selection border */ } QMenu::item:selected { border-color: darkblue; background: rgba(100, 100, 100, 150); } QMenu::icon:checked { /* appearance of a 'checked' icon */ background: gray; border: 1px inset gray; position: absolute; top: 1px; right: 1px; bottom: 1px; left: 1px; } QMenu::separator { height: 2px; background: lightblue; margin-left: 10px; margin-right: 5px; } QMenu::indicator { width: 13px; height: 13px; } /* non-exclusive indicator = check box style indicator (see QActionGroup::setExclusive) */ QMenu::indicator:non-exclusive:unchecked { image: url(:/images/checkbox_unchecked.png); } QMenu::indicator:non-exclusive:unchecked:selected { image: url(:/images/checkbox_unchecked_hover.png); } QMenu::indicator:non-exclusive:checked { image: url(:/images/checkbox_checked.png); } QMenu::indicator:non-exclusive:checked:selected { image: url(:/images/checkbox_checked_hover.png); } /* exclusive indicator = radio button style indicator (see QActionGroup::setExclusive) */ QMenu::indicator:exclusive:unchecked { image: url(:/images/radiobutton_unchecked.png); } QMenu::indicator:exclusive:unchecked:selected { image: url(:/images/radiobutton_unchecked_hover.png); } QMenu::indicator:exclusive:checked { image: url(:/images/radiobutton_checked.png); } QMenu::indicator:exclusive:checked:selected { image: url(:/images/radiobutton_checked_hover.png); }
自定义 QMenuBar
QMenuBar 的样式如下:
QMenuBar { background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 lightgray, stop:1 darkgray); spacing: 3px; /* spacing between menu bar items */ } QMenuBar::item { padding: 1px 4px; background: transparent; border-radius: 4px; } QMenuBar::item:selected { /* when selected using mouse or keyboard */ background: #a8a8a8; } QMenuBar::item:pressed { background: #888888; }
自定义 QProgressBar
QProgressBar 的边框、块和文本对齐方式可使用样式表进行自定义。但是,如果自定义了一个属性或子控件,则必须同时自定义所有其他属性或子控件。
QProgressBar { border: 2px solid grey; border-radius: 5px; } QProgressBar::chunk { background-color: #05B8CC; width: 20px; }
剩下的就是文本对齐,我们通过将文本定位在进度条的中心来进行自定义。
QProgressBar { border: 2px solid grey; border-radius: 5px; text-align: center; }
我们还可以添加边距,以获得更明显的分块。
在上面的截图中,我们使用了 0.5 像素的边距。
QProgressBar::chunk { background-color: #CD96CD; width: 10px; margin: 0.5px; }
自定义 QPushButton
QPushButton 的样式如下:
QPushButton { border: 2px solid #8f8f91; border-radius: 6px; background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #f6f7fa, stop: 1 #dadbde); min-width: 80px; } QPushButton:pressed { background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #dadbde, stop: 1 #f6f7fa); } QPushButton:flat { border: none; /* no border for a flat push button */ } QPushButton:default { border-color: navy; /* make the default button prominent */ }
对于带有菜单的QPushButton ,使用::menu-indicator子控件。
QPushButton:open { /* when the button has its menu open */ background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #dadbde, stop: 1 #f6f7fa); } QPushButton::menu-indicator { image: url(menu_indicator.png); subcontrol-origin: padding; subcontrol-position: bottom right; } QPushButton::menu-indicator:pressed, QPushButton::menu-indicator:open { position: relative; top: 2px; left: 2px; /* shift the arrow by 2 px */ }
可选中的QPushButton 设置了:checked 伪状态。
自定义 QRadioButton
QRadioButton 的指示器可通过以下方式更改:
QRadioButton::indicator { width: 13px; height: 13px; } QRadioButton::indicator::unchecked { image: url(:/images/radiobutton_unchecked.png); } QRadioButton::indicator:unchecked:hover { image: url(:/images/radiobutton_unchecked_hover.png); } QRadioButton::indicator:unchecked:pressed { image: url(:/images/radiobutton_unchecked_pressed.png); } QRadioButton::indicator::checked { image: url(:/images/radiobutton_checked.png); } QRadioButton::indicator:checked:hover { image: url(:/images/radiobutton_checked_hover.png); } QRadioButton::indicator:checked:pressed { image: url(:/images/radiobutton_checked_pressed.png); }
自定义 QScrollBar
QScrollBar 可以使用其子控件(如handle、add-line、sub-line 等)进行样式设置。请注意,如果自定义了一个属性或子控件,则必须同时自定义所有其他属性或子控件。
上面的滚动条是海蓝色的,边框为纯灰色。
QScrollBar:horizontal { border: 2px solid grey; background: #32CC99; height: 15px; margin: 0px 20px 0 20px; } QScrollBar::handle:horizontal { background: white; min-width: 20px; } QScrollBar::add-line:horizontal { border: 2px solid grey; background: #32CC99; width: 20px; subcontrol-position: right; subcontrol-origin: margin; } QScrollBar::sub-line:horizontal { border: 2px solid grey; background: #32CC99; width: 20px; subcontrol-position: left; subcontrol-origin: margin; }
左箭头和右箭头的边框为纯灰色,背景为白色。您也可以嵌入箭头图像作为替代。
QScrollBar::left-arrow:horizontal, QScrollBar::right-arrow:horizontal { border: 2px solid grey; width: 3px; height: 3px; background: white; } QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal { background: none; }
如果想让滚动条上的滚动按钮像 macOS 上那样放在一起(而不是边缘),可以使用下面的样式表:
QScrollBar:horizontal { border: 2px solid green; background: cyan; height: 15px; margin: 0px 40px 0 0px; } QScrollBar::handle:horizontal { background: gray; min-width: 20px; } QScrollBar::add-line:horizontal { background: blue; width: 16px; subcontrol-position: right; subcontrol-origin: margin; border: 2px solid black; } QScrollBar::sub-line:horizontal { background: magenta; width: 16px; subcontrol-position: top right; subcontrol-origin: margin; border: 2px solid black; position: absolute; right: 20px; } QScrollBar::left-arrow:horizontal, QScrollBar::right-arrow:horizontal { width: 3px; height: 3px; background: pink; } QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal { background: none; }
使用上述样式表的滚动条如下所示:
要自定义垂直滚动条,请使用类似下面的样式表:
QScrollBar:vertical { border: 2px solid grey; background: #32CC99; width: 15px; margin: 22px 0 22px 0; } QScrollBar::handle:vertical { background: white; min-height: 20px; } QScrollBar::add-line:vertical { border: 2px solid grey; background: #32CC99; height: 20px; subcontrol-position: bottom; subcontrol-origin: margin; } QScrollBar::sub-line:vertical { border: 2px solid grey; background: #32CC99; height: 20px; subcontrol-position: top; subcontrol-origin: margin; } QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical { border: 2px solid grey; width: 3px; height: 3px; background: white; } QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { background: none; }
自定义 QSizeGrip
QSizeGrip 通常只需设置一个图像即可。
QSizeGrip { image: url(:/images/sizegrip.png); width: 16px; height: 16px; }
自定义 QSlider
你可以如下所示为水平滑块设置样式:
QSlider::groove:horizontal { border: 1px solid #999999; height: 8px; /* the groove expands to the size of the slider by default. by giving it a height, it has a fixed size */ background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #B1B1B1, stop:1 #c4c4c4); margin: 2px 0; } QSlider::handle:horizontal { background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #b4b4b4, stop:1 #8f8f8f); border: 1px solid #5c5c5c; width: 18px; margin: -2px 0; /* handle is placed by default on the contents rect of the groove. Expand outside the groove */ border-radius: 3px; }
如果要更改手柄前后滑块部分的颜色,可以使用 add-page 和 sub-page 子控件。例如,垂直滑块:
QSlider::groove:vertical { background: red; position: absolute; /* absolutely position 4px from the left and right of the widget. setting margins on the widget should work too... */ left: 4px; right: 4px; } QSlider::handle:vertical { height: 10px; background: green; margin: 0 -4px; /* expand outside the groove */ } QSlider::add-page:vertical { background: white; } QSlider::sub-page:vertical { background: pink; }
自定义 QSpinBox
QSpinBox 可以完全自定义,如下所示(样式表有内联注释):
QSpinBox { padding-right: 15px; /* make room for the arrows */ border-image: url(:/images/frame.png) 4; border-width: 3; } QSpinBox::up-button { subcontrol-origin: border; subcontrol-position: top right; /* position at the top right corner */ width: 16px; /* 16 + 2*1px border-width = 15px padding + 3px parent border */ border-image: url(:/images/spinup.png) 1; border-width: 1px; } QSpinBox::up-button:hover { border-image: url(:/images/spinup_hover.png) 1; } QSpinBox::up-button:pressed { border-image: url(:/images/spinup_pressed.png) 1; } QSpinBox::up-arrow { image: url(:/images/up_arrow.png); width: 7px; height: 7px; } QSpinBox::up-arrow:disabled, QSpinBox::up-arrow:off { /* off state when value is max */ image: url(:/images/up_arrow_disabled.png); } QSpinBox::down-button { subcontrol-origin: border; subcontrol-position: bottom right; /* position at bottom right corner */ width: 16px; border-image: url(:/images/spindown.png) 1; border-width: 1px; border-top-width: 0; } QSpinBox::down-button:hover { border-image: url(:/images/spindown_hover.png) 1; } QSpinBox::down-button:pressed { border-image: url(:/images/spindown_pressed.png) 1; } QSpinBox::down-arrow { image: url(:/images/down_arrow.png); width: 7px; height: 7px; } QSpinBox::down-arrow:disabled, QSpinBox::down-arrow:off { /* off state when value in min */ image: url(:/images/down_arrow_disabled.png); }
自定义 QSplitter
QSplitter 源自QFrame ,因此可以像QFrame 一样设计样式。使用::handle子控件可以自定义手柄。
QSplitter::handle { image: url(images/splitter.png); } QSplitter::handle:horizontal { width: 2px; } QSplitter::handle:vertical { height: 2px; } QSplitter::handle:pressed { url(images/splitter_pressed.png); }
自定义 QStatusBar
我们可以为状态栏提供背景,并为状态栏中的项目提供边框,具体如下:
QStatusBar { background: brown; } QStatusBar::item { border: 1px solid red; border-radius: 3px; }
请注意,已添加到QStatusBar 的部件可使用后代声明(即)
QStatusBar QLabel { border: 3px solid white; }
自定义 QTabWidget 和 QTabBar
对于上面的截图,我们需要如下样式表:
QTabWidget::pane { /* The tab widget frame */ border-top: 2px solid #C2C7CB; } QTabWidget::tab-bar { left: 5px; /* move to the right by 5px */ } /* Style the tab using the tab sub-control. Note that it reads QTabBar _not_ QTabWidget */ QTabBar::tab { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #E1E1E1, stop: 0.4 #DDDDDD, stop: 0.5 #D8D8D8, stop: 1.0 #D3D3D3); border: 2px solid #C4C4C3; border-bottom-color: #C2C7CB; /* same as the pane color */ border-top-left-radius: 4px; border-top-right-radius: 4px; min-width: 8ex; padding: 2px; } QTabBar::tab:selected, QTabBar::tab:hover { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #fafafa, stop: 0.4 #f4f4f4, stop: 0.5 #e7e7e7, stop: 1.0 #fafafa); } QTabBar::tab:selected { border-color: #9B9B9B; border-bottom-color: #C2C7CB; /* same as pane color */ } QTabBar::tab:!selected { margin-top: 2px; /* make non-selected tabs look smaller */ }
通常,我们要求标签重叠后的效果如下所示:
对于上图这样的标签部件,我们可以使用负边距。负值会使元素与其相邻元素的距离比默认值更近。最终的样式表如下
QTabWidget::pane { /* The tab widget frame */ border-top: 2px solid #C2C7CB; } QTabWidget::tab-bar { left: 5px; /* move to the right by 5px */ } /* Style the tab using the tab sub-control. Note that it reads QTabBar _not_ QTabWidget */ QTabBar::tab { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #E1E1E1, stop: 0.4 #DDDDDD, stop: 0.5 #D8D8D8, stop: 1.0 #D3D3D3); border: 2px solid #C4C4C3; border-bottom-color: #C2C7CB; /* same as the pane color */ border-top-left-radius: 4px; border-top-right-radius: 4px; min-width: 8ex; padding: 2px; } QTabBar::tab:selected, QTabBar::tab:hover { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #fafafa, stop: 0.4 #f4f4f4, stop: 0.5 #e7e7e7, stop: 1.0 #fafafa); } QTabBar::tab:selected { border-color: #9B9B9B; border-bottom-color: #C2C7CB; /* same as pane color */ } QTabBar::tab:!selected { margin-top: 2px; /* make non-selected tabs look smaller */ } /* make use of negative margins for overlapping tabs */ QTabBar::tab:selected { /* expand/overlap to the left and right by 4px */ margin-left: -4px; margin-right: -4px; } QTabBar::tab:first:selected { margin-left: 0; /* the first selected tab has nothing to overlap with on the left */ } QTabBar::tab:last:selected { margin-right: 0; /* the last selected tab has nothing to overlap with on the right */ } QTabBar::tab:only-one { margin: 0; /* if there is only one tab, we don't want overlapping margins */ }
要将标签栏移到中间(如下图),我们需要使用以下样式表:
QTabWidget::pane { /* The tab widget frame */ border-top: 2px solid #C2C7CB; position: absolute; top: -0.5em; } QTabWidget::tab-bar { alignment: center; } /* Style the tab using the tab sub-control. Note that it reads QTabBar _not_ QTabWidget */ QTabBar::tab { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #E1E1E1, stop: 0.4 #DDDDDD, stop: 0.5 #D8D8D8, stop: 1.0 #D3D3D3); border: 2px solid #C4C4C3; border-bottom-color: #C2C7CB; /* same as the pane color */ border-top-left-radius: 4px; border-top-right-radius: 4px; min-width: 8ex; padding: 2px; } QTabBar::tab:selected, QTabBar::tab:hover { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #fafafa, stop: 0.4 #f4f4f4, stop: 0.5 #e7e7e7, stop: 1.0 #fafafa); } QTabBar::tab:selected { border-color: #9B9B9B; border-bottom-color: #C2C7CB; /* same as pane color */ }
撕裂指示器和滚动按钮可按以下方式进一步自定义:
QTabBar::tear { image: url(tear_indicator.png); } QTabBar::scroller { /* the width of the scroll buttons */ width: 20px; } QTabBar QToolButton { /* the scroll buttons are tool buttons */ border-image: url(scrollbutton.png) 2; border-width: 2px; } QTabBar QToolButton::right-arrow { /* the arrow mark in the tool buttons */ image: url(rightarrow.png); } QTabBar QToolButton::left-arrow { image: url(leftarrow.png); }
自 Qt 4.6 起,关闭按钮可按如下方式自定义:
QTabBar::close-button { image: url(close.png) subcontrol-position: left; } QTabBar::close-button:hover { image: url(close-hover.png) }
自定义 QTableView
假设我们希望QTableView 中的选中项的背景为淡入白色的泡泡糖粉色。
可以使用selection-background-color属性来实现,所需的语法如下:
QTableView { selection-background-color: qlineargradient(x1: 0, y1: 0, x2: 0.5, y2: 0.5, stop: 0 #FF92BB, stop: 1 white); }
可以使用以下样式表自定义角部件
QTableView QTableCornerButton::section { background: red; border: 2px outset red; }
QTableView 的复选框指示器也可以自定义。在下面的代码段中,自定义了未选中状态下的指示器background-color
:
QTableView::indicator:unchecked { background-color: #d7d6d5 }
自定义 QToolBar
QToolBar 的背景和句柄可按如下方式定制:
QToolBar { background: red; spacing: 3px; /* spacing between items in the tool bar */ } QToolBar::handle { image: url(handle.png); }
自定义 QToolBox
QToolBox 的标签可通过 "标签 "子控件进行自定义。
QToolBox::tab { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #E1E1E1, stop: 0.4 #DDDDDD, stop: 0.5 #D8D8D8, stop: 1.0 #D3D3D3); border-radius: 5px; color: darkgray; } QToolBox::tab:selected { /* italicize selected tabs */ font: italic; color: white; }
自定义 QToolButton
QToolButton 有三种类型。
- QToolButton 没有菜单。在这种情况下,QToolButton 的样式与QPushButton 完全相同。有关示例,请参阅自定义 QPushButton。
- QToolButton 有菜单,且QToolButton::popupMode 设置为QToolButton::DelayedPopup 或QToolButton::InstantPopup 。在这种情况下,QToolButton 的样式与有菜单的QPushButton 完全相同。有关菜单指示器伪状态的使用示例,请参阅定制 QPushButton。
- QToolButton 的QToolButton::popupMode 设置为QToolButton::MenuButtonPopup 。在这种情况下,我们将其样式设置如下:
QToolButton { /* all types of tool button */ border: 2px solid #8f8f91; border-radius: 6px; background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #f6f7fa, stop: 1 #dadbde); } QToolButton[popupMode="1"] { /* only for MenuButtonPopup */ padding-right: 20px; /* make way for the popup button */ } QToolButton:pressed { background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #dadbde, stop: 1 #f6f7fa); } /* the subcontrols below are used only in the MenuButtonPopup mode */ QToolButton::menu-button { border: 2px solid gray; border-top-right-radius: 6px; border-bottom-right-radius: 6px; /* 16px width + 4px for border = 20px allocated above */ width: 16px; } QToolButton::menu-arrow { image: url(downarrow.png); } QToolButton::menu-arrow:open { top: 1px; left: 1px; /* shift it a bit */ }
自定义 QToolTip
QToolTip 的自定义方式与 完全相同。此外,对于支持该功能的平台,还可以设置不透明度属性来调整不透明度。QLabel
例如
QToolTip { border: 2px solid darkkhaki; padding: 5px; border-radius: 3px; opacity: 200; }
自定义 QTreeView
可使用以下样式表自定义交替行的背景颜色:
QTreeView { alternate-background-color: yellow; }
要在项目悬停时提供特殊背景,我们可以使用::item子控件。例如
QTreeView { show-decoration-selected: 1; } QTreeView::item { border: 1px solid #d9d9d9; border-top-color: transparent; border-bottom-color: transparent; } QTreeView::item:hover { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #e7effd, stop: 1 #cbdaf1); border: 1px solid #bfcde4; } QTreeView::item:selected { border: 1px solid #567dbc; } QTreeView::item:selected:active{ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #6ea1f1, stop: 1 #567dbc); } QTreeView::item:selected:!active { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #6b9be8, stop: 1 #577fbf); }
QTreeView 的分支可使用::branch子控件进行样式设置。下面的样式表对绘制分支时的各种状态进行了颜色编码。
QTreeView::branch { background: palette(base); } QTreeView::branch:has-siblings:!adjoins-item { background: cyan; } QTreeView::branch:has-siblings:adjoins-item { background: red; } QTreeView::branch:!has-children:!has-siblings:adjoins-item { background: blue; } QTreeView::branch:closed:has-children:has-siblings { background: pink; } QTreeView::branch:has-children:!has-siblings:closed { background: gray; } QTreeView::branch:open:has-children:has-siblings { background: magenta; } QTreeView::branch:open:has-children:!has-siblings { background: green; }
虽然色彩丰富,但可以使用以下图片制作更有用的示例:
![]() | ![]() | ![]() | ![]() | ![]() |
vline.png | 分支-更多.png | 分支末端.png | 分支-关闭.png | 分支打开.png |
QTreeView::branch:has-siblings:!adjoins-item { border-image: url(vline.png) 0; } QTreeView::branch:has-siblings:adjoins-item { border-image: url(branch-more.png) 0; } QTreeView::branch:!has-children:!has-siblings:adjoins-item { border-image: url(branch-end.png) 0; } QTreeView::branch:has-children:!has-siblings:closed, QTreeView::branch:closed:has-children:has-siblings { border-image: none; image: url(branch-closed.png); } QTreeView::branch:open:has-children:!has-siblings, QTreeView::branch:open:has-children:has-siblings { border-image: none; image: url(branch-open.png); }
生成的树视图如下所示
常见错误
本节列出了使用样式表时的一些常见错误。
QPushButton 和图像
在设计QPushButton 时,通常希望使用图像作为按钮图形。使用background-image属性是一种常见的做法,但这种做法有很多缺点:例如,背景通常会隐藏在按钮装饰后面,因为它不被视为背景。此外,如果调整按钮大小,整个背景将被拉伸或平铺,这并不总是很好看。
最好使用border-image属性,因为无论背景如何,它都会显示图像(如果图像中有 Alpha 值,还可以将其与背景相结合),而且它有特殊设置来处理按钮大小调整。
请看下面的代码段:
QPushButton { color: grey; border-image: url(/home/kamlie/code/button.png) 3 10 3 10; border-top: 3px transparent; border-bottom: 3px transparent; border-right: 10px transparent; border-left: 10px transparent; }
这将产生一个如下所示的按钮:
url后面的数字分别表示顶部、右侧、底部和左侧的像素数。这些数字与边框相对应,在尺寸发生变化时不应拉伸。无论何时调整按钮的大小,图像的中间部分都会向两个方向伸展,而样式表中指定的像素不会伸展。这样按钮的边框看起来会更自然,就像下面这样:
![]() |
有边框 |
![]() |
无边框 |
另请参阅 支持的 HTML 子集和QStyle 。
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.