本页内容

Qt 样式表示例

接下来,我们将通过几个示例来了解如何开始使用 Qt 样式表。

样式表的使用

自定义前景色和背景色

首先,我们将应用程序中所有QLineEdit的背景色设置为黄色。可以这样实现:

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 }

这意味着所有将 Qt 属性 `mandatoryField ` 设置为 `true` 的控件都将具有黄色背景。

然后,对于每个必填字段控件,我们只需动态创建一个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的原生主题引擎不允许我们指定按钮的背景色)。
  • 因此,该按钮是通过样式表渲染的。
  • 由于我们未为 `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 的填充矩形右侧中心位置(有关更多信息,请参阅subcontrol-origin)。

复杂选择器示例

既然红色似乎是我们最喜欢的颜色,让我们通过设置以下全局样式表,将QLineEdit 中的文本设为红色:

QLineEdit { color: red }

不过,我们希望通过将QLineEdit 显示为灰色,来直观地表明其为只读状态:

QLineEdit { color: red }
QLineEdit[readOnly="true"] { color: gray }

随后,我们的设计团队提出要求,希望注册表单中(object name registrationDialog )的所有QLineEdit控件都显示为棕色:

QLineEdit { color: red }
QLineEdit[readOnly="true"] { color: gray }
#registrationDialog QLineEdit { color: brown }

经过几次 UI 设计会议后,我们决定所有QDialog的QLineEdit都应采用棕色:

QLineEdit { color: red }
QLineEdit[readOnly="true"] { color: gray }
QDialog QLineEdit { color: brown }

小测验:如果我们在QDialog 中包含一个只读的QLineEdit ,会发生什么?[提示:上文的“冲突解决”部分解释了此类情况下的处理方式。]

自定义特定控件

本节通过示例说明如何使用样式表自定义特定小部件。

自定义 QAbstractScrollArea

任何QAbstractScrollArea (包括Item视图、QTextEdit 和QTextBrowser )的背景均可通过background属性进行设置。例如,要设置一张随滚动条一起滚动的背景图像:

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 采用“盒模型”进行样式设置。

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 的边框样式采用盒模型(Box Model)。要创建带有圆角的行编辑框,我们可以设置:

QLineEdit {
    border: 2px solid gray;
    border-radius: 10px;
    padding: 0 8px;
    background: yellow;
    selection-background-color: darkgray;
}

对于采用QLineEdit::Password 回显模式的行编辑控件,可通过以下方式设置密码字符显示效果:

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 的边框、分段和 文本对齐方式均可通过样式表进行自定义。但是,如果自定义了一个属性或子控件,则必须同时自定义所有其他属性或子控件。

进度条显示为30%

例如,我们将边框改为灰色,进度条块改为天蓝色。

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 */
}

可选中(Checkable)的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 的样式。请注意,如果自定义了一个属性或子控件,则必须同时自定义所有其他属性或子控件。

绿色装饰性滚动条

上方的滚动条采用海蓝色的样式,并带有实心灰色边框。

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);
}

您可以按以下方式自定义关闭按钮:

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 的选项卡是通过“tab”子控件进行自定义的。

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 { /* 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 完全相同。此外,对于支持该功能的平台,可设置 opacity 属性来调整透明度。

例如,

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.pngbranch-more.pngbranch-end.pngbranch-closed.pngbranch-open.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` 属性会更好,因为它始终会显示该图像,无论背景如何(如果图像包含透明度值,可以将其与背景结合使用),并且它还具有专门的设置来处理按钮的尺寸调整。

请看以下代码片段:

        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 后的数字分别表示顶部、右侧、底部和左侧的像素值。这些数值对应边框,在尺寸变化时不应被拉伸。 每当你调整按钮大小时,图片的中间部分会沿两个方向拉伸,而样式表中指定的像素值则不会拉伸。这使得按钮的边框看起来更自然,如下所示:

具有指定边框尺寸的按钮

带边框时

未指定边框大小的按钮

无边框

另请参阅 《Qt Widgets 的样式设计方法》、《 支持的HTML子集》以及《QStyle 》。

© 2026 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.