On this page

Styling Approaches for Qt Widgets

Qt Widgets offers three ways to change how widgets look:

  • A style draws every widget. Subclass QProxyStyle to adjust the platform style, or QCommonStyle to implement a complete custom look. This is the mechanism that Qt's own styles use, and the one to use in production applications.
  • StyleKit describes a design declaratively in QML and applies it to widgets through QStyleKitStyle, a QStyle implementation. The same style file also styles Qt Quick Controls.
  • Style sheets override individual visual properties with CSS-like rules. They are a tool for prototyping and for small, local adjustments, not for the production look of an application.

This page explains what each approach costs and when to choose it.

Choose an approach

The following table maps a styling goal to the mechanism that fits it.

GoalApproach
Keep the native look but change a few details, such as a metric, a color, or a style hintA QProxyStyle subclass
Give the application its own look, independent of the platform style, for example, on an embedded deviceA QCommonStyle subclass or a StyleKit style
Share one design between Qt Widgets and Qt Quick ControlsA StyleKit style
Offer light and dark variants of the same designA different QPalette for the same style, or a StyleKit theme
Try out colors, borders, and spacing quickly, or restyle a single widget during developmentA style sheet

Implement a style for production applications

A QStyle subclass draws widgets directly with QPainter, using the information in the QStyleOption that each widget passes to the style. A style has full control over every element, from a button bevel to the branches of a tree view, and it exercises that control at the cost of an ordinary paint operation: there are no rules to match and no per-widget state to recompute.

Choose the base class according to how much you want to change:

  • QProxyStyle wraps another style, by default the platform style, and lets you override selected functions such as drawPrimitive(), pixelMetric(), or styleHint(). Everything you don't override keeps the native look and behavior. Use it to adjust the platform style.
  • QCommonStyle implements the behavior that all of Qt's styles share and leaves the drawing to you. Use it as the base for a complete custom look. Styles and Style Aware Widgets walks through the style elements and shows how each widget is drawn.

Set the style once, before the application creates its windows:

#include <QtWidgets>

#include "customstyle.h"

int main(int argc, char *argv[])
{
    QApplication::setStyle(new CustomStyle);
    QApplication app(argc, argv);
    QSpinBox spinBox;
    spinBox.show();
    return app.exec();
}

Draw with the colors from the QPalette in the style option rather than with hard-coded colors. The same style then produces a light and a dark variant of the design from two palettes, without switching styles. Qt's Fusion style works this way.

To let users select the style from the command line with the -style option, or to share it between applications, build the style as a plugin. See QStylePlugin and How to Create Qt Plugins.

Describe the design in QML with StyleKit

StyleKit is a declarative styling system. A style is a QML file whose root object is a Style, which sets colors, sizes, radii, borders, and state-dependent variations for each control type. Properties propagate through a control hierarchy, so a value set once on abstractButton applies to every kind of button, and a style can define several named themes.

QStyleKitStyle is a QStyle implementation that reads such a style and paints widgets with QPainter. Qt Quick takes no part in the rendering. The same Style file also styles Qt Quick Controls, so an application that uses both toolkits maintains one design definition. Themes defined in the style are selected with setThemeName().

auto *style = new QStyleKitStyle(QStringLiteral(":/styles/MyStyle.qml"));
QApplication::setStyle(style);

QStyleKitStyle is available since Qt 6.12. StyleKit is a Qt Labs module, and its API may change between Qt releases. The StyleKit Widgets Example shows a widget application with several StyleKit styles and themes.

Use style sheets for prototyping

Qt Style Sheets change the appearance of widgets through rules in a CSS-like syntax, without writing C++. They are convenient for trying out a design: edit a .qss file and restart the application, or pass the file with the -stylesheet command-line option, and Qt Widgets Designer previews the same rules. They are also the quickest way to mark a single widget, such as a mandatory field with a yellow background.

Style sheets have costs that make them unsuitable as the styling mechanism of a production application:

  • Every affected widget is drawn through the style sheet engine. When a style sheet is set, QWidget::style() returns a style sheet style that wraps the underlying style. For each widget it matches the selectors against the widget's class, object name, properties, and state, computes the rendering rules, and caches them per widget. The memory and processing cost grows with the number of widgets and rules.
  • Changing a style sheet repolishes everything it applies to. Each call to QApplication::setStyleSheet() discards the caches and repolishes every widget in the application, which recomputes fonts, palettes, geometry, and size hints and can visibly flicker. Don't build theme switching on style sheets.
  • A partial rule discards the native look. When a rule requests something the native style cannot honor, such as a background color for a QPushButton, the style sheet engine draws the whole element itself, without the native decoration. You then have to specify borders, padding, and every state yourself, and a small adjustment grows into a complete description of the look. See Customizing Qt Widgets Using Style Sheets.
  • Selectors couple the design to implementation details. Rules match class names, object names, and property values. Renaming an object or replacing a widget class silently stops the rule from matching. Rules don't affect custom widgets that paint without the style.
  • Style sheets win over programmatic settings. A style sheet overrides fonts, palettes, and item colors set with functions such as QWidget::setFont() or QTreeWidgetItem::setBackground(), so the styling of a widget is no longer visible in one place.

For a side-by-side comparison of style sheets and QStyle subclasses, see the KDAB article Say No to Qt Style Sheets.

If you use style sheets anyway

For a prototype, or for the few local adjustments that a production application needs, keep the style sheet manageable:

  • Keep the rules in a .qss file, bundled with the Qt resource system. Set it once on the application with QApplication::setStyleSheet(), before the first window is shown, and leave it in place. Reserve QWidget::setStyleSheet() for adjustments that are truly local to one widget and its children.
  • Don't assemble style sheets from C++ strings. A style sheet set on a widget is parsed once for every widget it's set on, not once for every string, and each call to QWidget::setStyleSheet() repolishes the widget and all its children, even when the string didn't change. A string built with QString::arg() to reflect data, such as a red border for an invalid value, repolishes the widget on every update. Instead, express the difference with a selector on an object name or a Qt property in the one style sheet, and re-evaluate it as described in Customizing Using Dynamic Properties.
  • Don't hard-code colors. A literal color such as #ffffff fits one theme. Use palette(window), palette(text), and the other palette roles so that the style sheet follows the application palette, including a dark color scheme.
  • Don't size everything in pixels. A px value scales with the display but not with the user's font. Use em and ex lengths for paddings, margins, and sizes that should follow the font, and pt for font sizes.

Move from a style sheet to a style

When a prototype turns into a product, transfer the design to a style. Most style sheet constructs have a direct counterpart:

Style sheetQStyleStyleKit
ColorsQPalette roles, read from QStyleOption::paletteColor properties of the control, or a theme
border, padding, marginpixelMetric() and subElementRect()Border and size properties of the control
Pseudo-states such as :hover and :pressedQStyle::State flags in QStyleOption::stateState groups such as hovered and pressed
Subcontrols such as ::indicatordrawPrimitive() and drawControl() for the elementDelegate properties such as indicator

See also Styles and Style Aware Widgets, QStyle, QProxyStyle, QCommonStyle, Qt Labs StyleKit, and Qt Style Sheets.

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