CopperSpice API  1.9.1
Style Sheets Examples

The following documentation contains multiple example to show various ways of using a Style Sheet to configure the appearance of the widgets in your application.

Foreground and Background Colors

In block 1 the background color is set to yellow for every QLineEdit in the given application. If you want this style to apply only to the QLineEdit objects in a specific window set the style for the relevant window, such as myDialog as shown in block 2.

There are two different ways to apply a style to one specific widget. The first option is to assign a value to the name property, which is a property in QObject. Then specify the value of the name property after the class name. The code for this is shown in block 3a where "QLineEdit#lastName" is used. Another option is to set the background color style directly on the QLineEdit and omit the selector. This is shown in block 3b.

In block 4 we are setting both the background color and the text color.

// block 1
QApplication::instance()->setStyleSheet("QLineEdit { background-color: yellow }");
// block 2
myDialog->setStyleSheet("QLineEdit { background-color: green }");
QLineEdit *lineEdit_1 = new QLineEdit();
// block 3a
lineEdit_1->setObjectName("lastName");
myDialog->setStyleSheet("QLineEdit#lastName { background-color: green }");
// block 3b
lineEdit_1->setStyleSheet("background-color: green");
// block 4
lineEdit_1->setStyleSheet("color: white; background-color: blue");
See also
background color

Using Dynamic Properties

There are many situations where a form with mandatory fields is required. To indicate to the user a field is mandatory, one effective solution is to use yellow as the background color. This can be implemented using CopperSpice Style Sheets as follows.

This means that every widget whose mandatoryField CopperSpice property is set to true would have a yellow background.

[mandatoryField="true"] { background-color: yellow }

For each mandatory field widget, we simply create a mandatoryField property on the fly and set it to 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);

Using the Box Model and a QPushButton

The example shows the simplest way to create a red QPushButton. The result is a flat button with no borders.

QPushButton#dangerButton { background-color: red }
A flat red button

The result may be a flat red rectangle with no border for the following reasons.

  • Setting the background color for a push button may not be supported by the native theme
  • No values were provided for the border-width and border-style, so by default we obtain a 0-pixel wide border of style none

To improve the styling specifying a border as shown below.

QPushButton#dangerButton {
background-color: red;
border-style: outset;
border-width: 2px;
border-color: beige;
}
A red button with a beige border

This version of our button has border however it is still a bit odd. Now we want to add some space between the border and the text using the padding property. Additionally, we will enforce a minimum width, round the corners, and specify a larger font to make the button look nicer.

QPushButton#dangerButton {
background-color: red;
border-style: outset;
border-width: 2px;
border-radius: 10px;
border-color: beige;
font: bold 14px;
min-width: 10em;
padding: 6px;
}
A red button with a round beige border and big, bold text

The only issue remaining is the button does not react when we press it. We can fix this by specifying a slightly different background color and use a different border style.

QPushButton#dangerButton {
background-color: red;
border-style: outset;
border-width: 2px;
border-radius: 10px;
border-color: beige;
font: bold 14px;
min-width: 10em;
padding: 6px;
}
QPushButton#dangerButton:pressed {
background-color: rgb(224, 0, 0);
border-style: inset;
}

QPushButton Menu Indicator

Subcontrols give access to the sub-elements of a widget. For example, a QPushButton associated with a menu (using QPushButton::setMenu()) has a menu indicator. This is how to customize the menu indicator for the red push button.

QPushButton#dangerButton::menu-indicator {
image: url(myindicator.png);
}

By default, the menu indicator is located at the bottom-right corner of the padding rectangle. We can change this by specifying subcontrol-position and subcontrol-origin to anchor the indicator differently. We can also use top and left to move the indicator by a few pixels.

QPushButton::menu-indicator {
image: url(myindicator.png);
subcontrol-position: right center;
subcontrol-origin: padding;
left: -2px;
}

This positions the myindicator.png to the center right of the QPushButton.

See also
subcontrol-origin, padding

Complex Selector Example

In this example we start by making the text in QLineEdit red by setting the following application wide stylesheet. We would also like to give a visual indication that a QLineEdit is read only by making it appear gray.

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

Now we add a requirement that every QLineEdit in our window with the name of "searchDialog" should have a text color of green. The style sheet is changed as shown below.

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

Now we have an issue since two rules will conflict. What text color is used for a QLineEdit in our searchDialog which the user can edit, should it be red or green? What about a read only QLineEdit which appears in a searchDialog, should it be gray or green? For information about how this issue is resolved refer to the documentation for Conflict Resolution.

Customizing Specific Widgets

This section provides examples to customize specific widgets using Style Sheets.

QAbstractScrollArea

The background of any QAbstractScrollArea (Item views, QTextEdit and QTextBrowser) can be set using the background properties. For example, to set a background-image that scrolls with the scroll bar.

background-color: white;
background-image: url(draft.png);
background-attachment: scroll;
}

If the background-image is to be fixed with the viewport:

background-color: white;
background-image: url(draft.png);
background-attachment: fixed;
}

QCheckBox

Styling of a QCheckBox is almost identical to styling a QRadioButton. The main difference is that a tristate QCheckBox has an indeterminate state.

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

We will look at an example where the drop down button of a QComboBox appears "merged" with the combo box frame.

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);
}
/* in 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);
}
/* 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;
}

The pop-up of the QComboBox is a QAbstractItemView and is styled using the descendant selector.

border: 2px solid darkgray;
selection-background-color: lightgray;
}

QDockWidget

The title bar and the buttons of a QDockWidget can be customized as follows.

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

If one desires to move the dock widget buttons to the left, the following style sheet can be used.

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

To customize the separator (resize handle) of a QDockWidget use QMainWindow::separator.

QFrame

A QFrame is styled using the box model.

border: 2px solid green;
border-radius: 4px;
padding: 2px;
background-image: url(images/welcome.png);
}

QGroupBox

This is an example which moves the QGroupBox title to the center.

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 */
}
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 #FFOECE, stop: 1 #FFFFFF);
}

For a checkable QGroupBox use the ::indicator subcontrol and style it exactly like a QCheckBox.

QGroupBox::indicator {
width: 13px;
height: 13px;
}
QGroupBox::indicator:unchecked {
image: url(:/images/checkbox_unchecked.png);
}

QHeaderView

QHeaderView can be customized as follows.

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

The frame of a QLineEdit is styled using the "The Box Model" to create a line edit with rounded corners.

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

The password character of line edits that have QLineEdit::Password echo mode can be set using.

QLineEdit[echoMode="2"] {
lineedit-password-character: 9679;
}

The background of a read only QLineEdit can be modified as below:

QLineEdit:read-only {
background: lightblue;
}

QListView

The background color of alternating rows can be customized using the following style sheet.

alternate-background-color: yellow;
}

To provide a special background when you hover over items, we can use the ::item subcontrol. For example,

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

The separator of a QMainWindow can be styled as follows.

QMainWindow::separator {
background: yellow;
width: 10px; /* when vertical */
height: 10px; /* when horizontal */
}
QMainWindow::separator:hover {
background: red;
}

QMenu

Individual items of a QMenu are styled using the 'item' subcontrol as follows.

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

For a more advanced customization, use a style sheet as follows.

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 */
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 */
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 is styled as follows.

background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 lightgray, stop:1 darkgray);
}
QMenuBar::item {
spacing: 3px; /* spacing between menu bar items */
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

The QProgressBar border, chunk, and text-align can be customized using style sheets. However, if one property or subcontrol is customized, all the other properties or subcontrols must be customized.

For example, we change the border to grey and the chunk to cerulean.

border: 2px solid grey;
border-radius: 5px;
}
QProgressBar::chunk {
background-color: #05B8CC;
width: 20px;
}

This leaves the text-align, which we customize by positioning the text in the center of the progress bar.

border: 2px solid grey;
border-radius: 5px;
text-align: center;
}

A margin can be included to obtain more visible chunks.

QProgressBar::chunk {
background-color: #CD96CD;
width: 10px;
margin: 0.5px;
}

QPushButton

A QPushButton is styled as follows.

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);
}
border: none; /* no border for a flat push button */
}
QPushButton:default {
border-color: navy; /* make the default button prominent */
}

For a QPushButton with a menu, use the ::menu-indicator subcontrol.

/* 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 have the :checked pseudo state set.

QRadioButton

The indicator of a QRadioButton can be changed using the following style.

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

The QScrollBar can be styled using its subcontrols like handle, add-line, sub-line, and so on. If one property or subcontrol is customized, all the other properties or subcontrols must be customized as well.

The scroll bar above has been styled in aquamarine with a solid grey border.

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

The left-arrow and right-arrow have a solid grey border with a white background. As an alternative, you could also embed the image of an arrow.

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

If you want the scroll buttons of the scroll bar to be placed together (instead of the edges) like on Mac OS X, you can use the following stylesheet.

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

The scroll bar using the above stylesheet looks like this.

To customize a vertical scroll bar use a style sheet similar to the following.

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 is usually styled by just setting an image.

image: url(:/images/sizegrip.png);
width: 16px;
height: 16px;
}

QSlider

You can style horizontal slider as below.

QSlider::groove:horizontal {
border: 1px solid #999999;
height: 8px; /* groove expands by default, sets 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 on the contents of the groove, expand outside the groove */
border-radius: 3px;
}

If you want to change the color of the slider parts before and after the handle, you can use the add-page and sub-page subcontrols. For example, for a vertical slider.

QSlider::groove:vertical {
background: red;
position: absolute; /* position 4px from the left and right of the widget */
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 can be customized as shown below.

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;
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;
}
/* off state when value is max */
QSpinBox::up-arrow:disabled, QSpinBox::up-arrow:off {
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;
}
/* off state when value is min */
QSpinBox::down-arrow:disabled,
QSpinBox::down-arrow:off {
image: url(:/images/down_arrow_disabled.png);
}

QSplitter

A QSplitter derives from a QFrame and can be styled like a QFrame. The grip or the handle is customized using the handle subcontrol.

image: url(images/splitter.png);
}
QSplitter::handle:horizontal {
width: 2px;
}
height: 2px;
}
image: url(images/splitter_pressed.png);
}

QStatusBar

We can provide a background for the status bar and a border for items inside the status bar as follows.

background: brown;
}
QStatusBar::item {
border: 1px solid red;
border-radius: 3px;
}

Widgets that have been added to the QStatusBar can be styled using the descendant declaration.

border: 3px solid white;
}

QTabWidget and QTabBar

For this image we need a stylesheet as shown below.

/* tab widget frame */
QTabWidget::pane {
border-top: 2px solid #C2C7CB;
}
QTabWidget::tab-bar {
left: 5px; /* move to the right by 5px */
}
/* Style the tab using the tab subcontrol. */
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 */
}

Often we require the tabs to overlap to look like below.

For a tab widget that looks like above, we make use of negative margins. The resulting stylesheet looks like this.

QTabWidget::pane {
border-top: 2px solid #C2C7CB; /* tab widget frame */
}
QTabWidget::tab-bar {
left: 5px; /* move to the right by 5px */
}
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 */
}
/* use negative margins for overlapping tabs */
QTabBar::tab:selected {
margin-left: -4px; /* expand/overlap to the left and right by 4px */
margin-right: -4px;
}
QTabBar::tab:first:selected {
margin-left: 0; /* first selected tab has nothing to overlap with on the left */
}
QTabBar::tab:last:selected {
margin-right: 0; /* last selected tab has nothing to overlap with on the right */
}
QTabBar::tab:only-one {
margin: 0; /* if there is only one tab, do not want overlapping margins */
}

To move the tab bar to the center (as below), we require the following stylesheet.

QTabWidget::pane {
border-top: 2px solid #C2C7CB; /* tab widget frame */
position: absolute;
top: -0.5em;
}
QTabWidget::tab-bar {
alignment: center;
}
/* Style the tab using the tab subcontrol */
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 */
}

The tear indicator and the scroll buttons can be further customized as follows:

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

The close button can be customized as follow.

image: url(close.png)
subcontrol-position: left;
}
QTabBar::close-button:hover {
image: url(close-hover.png)
}

QTableView

Suppose we like our selected item in QTableView to have pink fade to white as its background.

This is possible with the selection-background-color property.

selection-background-color: qlineargradient(x1: 0, y1: 0, x2: 0.5, y2: 0.5,
stop: 0 #FF92BB, stop: 1 white);
}

The corner widget can be customized using the following style sheet.

QTableView QTableCornerButton::section {
background: red;
border: 2px outset red;
}

QToolBar

The background and the handle of a QToolBar is customized as shown below.

background: red;
spacing: 3px; /* spacing between items in the toolbar */
}
QToolBar::handle {
image: url(handle.png);
}

QToolBox

The tabs of the QToolBox are customized using the 'tab' subcontrol.

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

There are three types for QToolButton.

  • Has no menu and styled exactly like QPushButton.
  • Has a menu and has the QToolButton::popupMode set to QToolButton::DelayedPopup or QToolButton::InstantPopup. In this case the QToolButton is styled exactly like a QPushButton with a menu.
  • Has QToolButton::popupMode set to QToolButton::MenuButtonPopup, in this case we style it as shown below.

Refer to Customizing QPushButton for an example of the menu-indicator pseudo state.

/* 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);
}
/* only for MenuButtonPopup */
QToolButton[popupMode="1"] {
padding-right: 20px; /* make room for the popup button */
}
QToolButton:pressed {
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #dadbde, stop: 1 #f6f7fa);
}
/* subcontrols below are used only in the MenuButtonPopup mode */
border: 2px solid gray;
border-top-right-radius: 6px;
border-bottom-right-radius: 6px;
width: 16px;
}
image: url(downarrow.png);
}
QToolButton::menu-arrow:open {
top: 1px; left: 1px; /* shift it a bit */
}

QToolTip

QToolTip is customized exactly like a QLabel. In addition for platforms which support this, the opacity property may be set to adjust the opacity.

border: 2px solid darkkhaki;
padding: 5px;
border-radius: 3px;
opacity: 200;
}

QTreeView

The background color of alternating rows can be customized using the following style sheet.

alternate-background-color: yellow;
}

To provide a special background when you hover over items, we can use the ::item subcontrol.

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

The branches of a QTreeView are styled using the ::branch subcontrol. The following stylesheet color codes the various states when drawing a 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;
}

Colorful is a more useful example and it uses the following images.

vline.pngbranch-more.png branch-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);
}

This is how the resulting tree view will look.

Common Mistakes

This section lists some common mistakes when using stylesheets.

Buttons and Images

When styling a QPushButton it is often desirable to use an image as the button graphic. It is common to try the background-image property, but this has a number of drawbacks. For instance, the background will often appear hidden behind the button decoration, because it is not considered a background. In addition, if the button is resized, the entire background will be stretched or tiled, which does not always look good.

It is better to use the border-image property, as it will always display the image, regardless of the background (you can combine it with a background if it has alpha values in it), and it has special settings to deal with button resizing.

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

This code will produce a button which looks like the following.

The numbers after the url gives the top, right, bottom and left number of pixels, respectively. These numbers correspond to the border and should not stretch when the size changes. Whenever you resize the button, the middle part of the image will stretch in both directions, while the pixels specified in the stylesheet will not. This makes the borders of the button look more natural

With borders
Without borders
See also
QStyle, Supported HTML Subset