Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
styles-drawing.qdoc
Go to the documentation of this file.
1
// Copyright (C) 2026 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
3
4
/*!
5
\page style-drawing.html
6
\title How a Style Draws a Widget
7
\brief The style elements, style options, and QStyle functions that turn a
8
widget into pixels.
9
10
The \l QStyle API has three kinds of functions: functions that draw the
11
widgets, static helpers for common and difficult tasks such as calculating
12
the position of a slider handle, and functions for the calculations that
13
widgets need while drawing, for example, to compute their size hints. The
14
style also helps some widgets lay out their contents, and it can adjust the
15
\l QPalette that the widgets draw with.
16
17
This page describes the building blocks that a style implementation works
18
with. \l{Widget Style Reference} lists which of them each widget uses.
19
20
\section1 Style elements
21
22
\l QStyle draws graphical elements. An element is a widget or a widget part,
23
such as a push button bevel, a window frame, or a scroll bar. Most drawing
24
functions take four arguments:
25
26
\list
27
\li An enum value that specifies which graphical element to draw.
28
\li A \l QStyleOption that specifies how and where to render that element.
29
\li A \l QPainter to draw the element with.
30
\li The \l QWidget that the drawing is performed on. This argument is
31
optional.
32
\endlist
33
34
When a widget asks a style to draw an element, it provides the style with a
35
\l QStyleOption, a class that contains the information necessary for
36
drawing. Because the option carries everything the style needs, the style
37
can draw widgets without linking any widget code. You can draw a combo box
38
on any paint device, not only on a \l QComboBox.
39
40
The widget is passed as the last argument in case the style needs it for
41
special effects, such as animated default buttons on \macos, but the style
42
can't rely on it. Widgets that draw several elements themselves pass
43
themselves, and so does \l QStylePainter. Code that draws directly on a
44
paint device may pass \nullptr.
45
46
A widget consists of a hierarchy, or tree, of style elements. For instance,
47
when a style receives a request to draw a push button, it draws a label
48
(text and icon), a button bevel, and a focus frame. The button bevel in turn
49
consists of a frame around the bevel and the panel. The following conceptual
50
tree shows the push button elements in drawing order, with nested elements
51
drawn by the element above them:
52
53
\list
54
\li Push button
55
\list
56
\li Button bevel
57
\list
58
\li Default button frame
59
\li Button panel
60
\endlist
61
\li Label (icon and text)
62
\li Focus frame
63
\endlist
64
\endlist
65
66
\l{Styling Buttons and Input Widgets#Push buttons}{Push buttons} in the
67
reference shows the actual tree for \l QPushButton, with the element names.
68
69
Widgets don't necessarily ask the style to draw only one element. A widget
70
can make several calls to the style to draw different elements. An example
71
is \l QTabWidget, which draws its tabs and frame individually.
72
73
There are three element types: primitive elements, control elements, and
74
complex control elements. The \l{QStyle::}{PrimitiveElement},
75
\l{QStyle::}{ControlElement}, and \l{QStyle::}{ComplexControl} enums define
76
them. The values of each enum have a prefix that identifies their type:
77
\c{PE_} for primitive elements, \c{CE_} for control elements, and \c{CC_}
78
for complex controls. The \l QStyle class documentation lists these elements
79
and their roles in styling widgets.
80
81
\section2 Primitive elements
82
83
Primitive elements are GUI elements that are common and often used by
84
several widgets. Examples are frames, button bevels, and arrows for spin
85
boxes, scroll bars, and combo boxes. Primitive elements can't exist on their
86
own; they are always part of a larger construct. They take no part in the
87
interaction with the user but are passive decorations in the GUI.
88
89
\section2 Control elements
90
91
A control element performs an action or displays information to the user.
92
Examples of control elements are push buttons, checkboxes, and header
93
sections in tables and tree views. A control element isn't always a complete
94
widget such as a push button; it can also be a widget part such as a tab bar
95
tab or a scroll bar slider. Control elements differ from primitive elements
96
in that they aren't passive: they take part in the interaction with the
97
user.
98
99
Controls that consist of several elements often use the style to calculate
100
the bounding rectangles of the elements. The \l{QStyle::}{SubElement} enum
101
defines the available subelements. This enum is only used for calculating
102
bounding rectangles. Subelements aren't graphical elements to be drawn like
103
primitive, control, and complex elements.
104
105
\section2 Complex control elements
106
107
Complex control elements contain subcontrols. Complex controls behave
108
differently depending on where the user handles them with the mouse and
109
which keyboard keys are pressed. This depends on which subcontrol, if any,
110
the mouse is over or pressed on. Examples of complex controls are scroll
111
bars and combo boxes. With a scroll bar, you can use the mouse to move the
112
slider and press the line up and line down buttons. The
113
\l{QStyle::}{SubControl} enum defines the available subcontrols.
114
115
In addition to drawing, the style tells the widgets which subcontrol, if
116
any, the user pressed. For instance, a \l QScrollBar needs to know whether
117
the user pressed the slider, the slider groove, or one of the buttons.
118
119
Subcontrols aren't the same as control elements. You can't use the style to
120
draw a subcontrol; the style only calculates the bounding rectangle in which
121
the subcontrol should be drawn. It's common, though, for complex elements to
122
use control and primitive elements to draw their subcontrols. Qt's built-in
123
styles do this frequently. For instance, \l QCommonStyle uses
124
\c PE_IndicatorCheckBox to draw the checkbox in group boxes, which is a sub
125
control of \c CC_GroupBox. Some subcontrols have an equivalent control
126
element, for example, the scroll bar slider (\c SC_ScrollBarSlider and
127
\c CE_ScrollBarSlider).
128
129
\section1 Subelements, subcontrols, and pixel metrics
130
131
The style elements and the widgets use the style to calculate the bounding
132
rectangles of subelements and subcontrols. Pixel metrics, which are
133
style-dependent sizes in screen pixels, are also used for measurements when
134
drawing. Three enums in \l QStyle represent the available rectangles and
135
pixel metrics: \l{QStyle::}{SubElement}, \l{QStyle::}{SubControl}, and
136
\l{QStyle::}{PixelMetric}. Their values start with \c{SE_}, \c{SC_}, and
137
\c{PM_}.
138
139
\section1 Style hints
140
141
The style also answers a set of style hints, represented by the values of
142
the \l{QStyle::}{StyleHint} enum. Not all widgets have the same
143
functionality and look in the different styles. For instance, when the menu
144
items in a menu don't fit in a single column on the screen, some styles
145
support scrolling while others draw more than one column to fit all items.
146
Widgets query hints with \l{QStyle::}{styleHint()}.
147
148
\section1 Standard icons
149
150
A style usually has a set of standard icons, such as warning, question, and
151
error images, for message boxes, file dialogs, and title bar buttons. The
152
\l{QStyle::}{StandardPixmap} enum names them, and
153
\l{QStyle::}{standardIcon()} returns the \l QIcon for a value. Qt's widgets
154
use these icons, so when you implement a style, supply them.
155
156
\section1 Layout spacing
157
158
The style calculates the spacing between widgets in layouts. There are two
159
ways to handle these calculations. You can return the spacing from
160
\l{QStyle::}{pixelMetric()} for \c PM_LayoutHorizontalSpacing and
161
\c PM_LayoutVerticalSpacing, which \l QCommonStyle does. Alternatively, you
162
can reimplement \l{QStyle::}{layoutSpacing()} if you need more control. In
163
that function, you can calculate the spacing based on the control types
164
(\l{QSizePolicy::ControlType}) of the two adjacent widgets, their size
165
policies (\l{QSizePolicy::Policy}), and the style option for the widget in
166
question.
167
168
\section1 Style options
169
170
The subclasses of \l QStyleOption contain all information necessary to style
171
the individual elements. The caller of the \l QStyle function instantiates a
172
style option, usually on the stack, and fills it out. Depending on what is
173
drawn, the style expects a different style option class. For example, the
174
\c PE_FrameFocusRect element expects a \l QStyleOptionFocusRect argument.
175
You can also create your own subclasses for a custom style to use. The style
176
options keep public variables for performance reasons.
177
178
Widgets can be in a number of different states, defined by the
179
\l{QStyle::}{State} enum. Some of the state flags have different meanings
180
depending on the widget, but others are common for all widgets, such as
181
\c State_Enabled. \l QStyleOption::initFrom() sets the common states; the
182
individual widgets set the rest.
183
184
Most notably, the style options contain the palette and bounding rectangle
185
of the widget to be drawn. Most widgets have specialized style options.
186
\l QPushButton and \l QCheckBox, for instance, use \l QStyleOptionButton,
187
which contains the text, the icon, and the size of the icon.
188
\l{Widget Style Reference} describes the exact contents of each option.
189
190
When you reimplement \l QStyle functions that take a \l QStyleOption
191
parameter, you often need to cast the option to a subclass, such as
192
\l QStyleOptionFocusRect. Use qstyleoption_cast() to ensure that the pointer
193
type is correct. If the object isn't of the right type, qstyleoption_cast()
194
returns \nullptr:
195
196
\snippet code/doc_src_qt4-styles.cpp 0
197
198
\section2 Common state flags and members
199
200
Some states and variables are common for all widgets. Widgets set them with
201
\l QStyleOption::initFrom(). Not all elements use this function. The widgets
202
create the style options, and for some elements the information from
203
\l{QStyleOption::}{initFrom()} isn't necessary.
204
205
\table 90%
206
\header
207
\li State
208
\li Set when
209
\row
210
\li \c State_Enabled
211
\li The widget isn't disabled (see \l{QWidget::isEnabled()}).
212
\row
213
\li \c State_HasFocus
214
\li The widget has focus (see \l{QWidget::hasFocus()}).
215
\row
216
\li \c State_KeyboardFocusChange
217
\li The user changed focus with the keyboard (see
218
\l{Qt::}{WA_KeyboardFocusChange}).
219
\row
220
\li \c State_MouseOver
221
\li The mouse cursor is over the widget.
222
\row
223
\li \c State_Active
224
\li The widget is a child of the active window.
225
\endtable
226
227
The other common members are:
228
229
\table 90%
230
\header
231
\li Member
232
\li Description
233
\row
234
\li \l{QStyleOption::}{rect}
235
\li The bounding rectangle of the element to draw. \c initFrom()
236
sets it to the widget's bounding rectangle
237
(\l{QWidget::rect()}).
238
\row
239
\li \l{QStyleOption::}{direction}
240
\li The layout direction, a value of the \l{Qt::LayoutDirection}
241
enum.
242
\row
243
\li \l{QStyleOption::}{palette}
244
\li The \l QPalette to use when drawing the element. \c initFrom()
245
sets it to the widget's palette (\l{QWidget::palette()}).
246
\row
247
\li \l{QStyleOption::}{fontMetrics}
248
\li The \l QFontMetrics to use when drawing text on the widget.
249
\row
250
\li \l{QStyleOption::}{styleObject}
251
\li The object that the option describes, usually the widget. Styles
252
use it to store animation state.
253
\endtable
254
255
The complex style options (classes that inherit \l{QStyleOptionComplex})
256
share two more variables: \l{QStyleOptionComplex::}{subControls} and
257
\l{QStyleOptionComplex::}{activeSubControls}. Both are OR combinations of
258
\l QStyle::SubControl values. They indicate which subcontrols the complex
259
control consists of and which of them are currently active.
260
261
\section1 QStyle functions
262
263
\l QStyle defines three functions for drawing the primitive, control, and
264
complex elements: \l{QStyle::}{drawPrimitive()},
265
\l{QStyle::}{drawControl()}, and \l{QStyle::}{drawComplexControl()}. They
266
take the arguments listed under \l{Style elements}.
267
268
Not all widgets pass a pointer to themselves. If the style option sent to
269
the function doesn't contain the information you need, check the widget
270
implementation to see whether it passes itself.
271
272
QStyle also provides helper functions for drawing elements.
273
\l{QStyle::}{drawItemText()} draws text within a specified rectangle, taking
274
a \l QPalette as a parameter. \l{QStyle::}{drawItemPixmap()} aligns a pixmap
275
within a specified bounding rectangle.
276
277
Other QStyle functions do calculations for the drawing functions. The
278
widgets also use them to calculate size hints and bounding rectangles when
279
they draw several style elements themselves. These functions typically take
280
the same arguments as the drawing functions.
281
282
\list
283
\li \l{QStyle::}{subElementRect()} takes a \l{QStyle::}{SubElement} value
284
and calculates the bounding rectangle of a subelement. The style uses
285
this function to know where to draw the different parts of an element.
286
If you create a new style, you can reuse the subelement positions of the
287
base class.
288
\li \l{QStyle::}{subControlRect()} calculates the bounding rectangles of the
289
subcontrols in complex controls. When you implement a new style,
290
reimplement it for the rectangles that differ from the base class.
291
\li \l{QStyle::}{pixelMetric()} returns a pixel metric, a style-dependent
292
size given in screen pixels. It takes a value of the
293
\l{QStyle::}{PixelMetric} enum. Pixel metrics don't have to be static
294
measurements; you can calculate them from the style option.
295
\li \l{QStyle::}{sizeFromContents()} returns the size of a widget for a
296
given contents size. Widgets use it to calculate their size hints.
297
\li \l{QStyle::}{hitTestComplexControl()} returns the subcontrol that the
298
mouse pointer is over in a complex control. Usually, this is a matter of
299
using \l{QStyle::}{subControlRect()} to get the bounding rectangles of
300
the subcontrols and finding the one that contains the position of the
301
cursor.
302
\endlist
303
304
QStyle also has the functions \l{QStyle::}{polish()} and
305
\l{QStyle::}{unpolish()}. Qt polishes every widget before it's shown for the
306
first time and again when the style changes, and unpolishes it when the
307
style changes or the widget is destroyed. Use these functions to set
308
attributes on the widgets or to do other work that your style requires. For
309
instance, if you need to know when the mouse is hovering over a widget, set
310
the \l{Qt::}{WA_Hover} widget attribute in \c polish(). The widget then sets
311
\c State_MouseOver in its style options. Overloads of \c polish() also let
312
the style prepare the \l QApplication and adjust the application palette;
313
see \l{The palette}.
314
315
Finally, QStyle has static helper functions for common and difficult tasks.
316
\l{QStyle::}{sliderPositionFromValue()} and
317
\l{QStyle::}{sliderValueFromPosition()} convert between slider values and
318
pixel positions. \l{QStyle::}{visualRect()}, \l{QStyle::}{visualPos()}, and
319
\l{QStyle::}{visualAlignment()} translate logical coordinates and alignments
320
to their mirrored counterparts in right-to-left layouts, and
321
\l{QStyle::}{alignedRect()} aligns a rectangle for the current direction.
322
For details, see \l{QStyle#Right-to-Left Desktops}{Right-to-Left Desktops}
323
in the \l QStyle class documentation.
324
325
When you reimplement QStyle virtual functions, handle the elements that
326
differ from the base class and call the base class implementation for
327
everything else.
328
329
\section1 The palette
330
331
Each style draws with a palette of brushes, provided by \l QPalette. There
332
is one set of colors, a \l QPalette::ColorGroup, for each widget state:
333
active for widgets in the window that has keyboard focus, inactive for
334
widgets in other windows, and disabled for widgets that are disabled. The
335
\c State_Active and \c State_Enabled state flags tell you which group to
336
use. Each group contains the color roles that \l QPalette::ColorRole
337
defines. The roles describe the situations the colors are meant for, such as
338
painting widget backgrounds, text, or buttons.
339
340
Each style decides how to use the color roles. For instance, if the style
341
uses gradients, it can take a palette color and make it darker or lighter
342
with \l QColor::darker() and \l QColor::lighter() to create the gradient. In
343
general, if you need a brush that the palette doesn't provide, derive it
344
from one that it does.
345
346
When you set a style on the application, Qt builds the application palette
347
from the style's \l{QStyle::}{standardPalette()}, lets the platform theme
348
override the roles it provides, and passes the result to
349
\l{QStyle::polish(QPalette &)}{QStyle::polish()}. Reimplement that overload
350
to adjust the colors your style needs. Qt doesn't override a palette that
351
the application set explicitly with \l QApplication::setPalette().
352
353
Don't hard-code colors. Applications and individual widgets can set their
354
own palette, and a style that draws from the palette follows them. It also
355
gets a light and a dark variant from two palettes, without any extra code.
356
Qt's Fusion style works this way:
357
358
\table
359
\row
360
\li \image styles/gallery-fusion-light.webp {Form with text field, combo
361
box, spin box, slider, checkbox, progress bar, and buttons in the Fusion
362
style with a light palette}
363
\li \image styles/gallery-fusion-dark.webp {Form with text field, combo box,
364
spin box, slider, checkbox, progress bar, and buttons in the Fusion
365
style with a dark palette}
366
\endtable
367
368
A style doesn't have to look good with every conceivable palette, but it
369
should honor the palette it's given.
370
371
\section1 Item views
372
373
Delegates paint the items in item views. Qt's default delegate,
374
\l QStyledItemDelegate, draws \c CE_ItemViewItem and calculates item sizes
375
with \c CT_ItemViewItem, so a style controls how items look without an
376
accompanying delegate. The style draws the item view headers, the tree
377
branch indicators, and the row backgrounds directly. To support new data
378
types or item data roles, you need a custom delegate; see
379
\l{Model/View Programming}.
380
381
\section1 Implementation advice
382
383
When you implement a style, read the code of the widgets and of the base
384
class. The widgets use the style in different ways, and the base class
385
implementation can affect the state of the drawing, for example, by altering
386
the \l QPainter state without restoring it, or by drawing some elements
387
without using the appropriate pixel metrics and subelements.
388
389
Don't change the proposed size of widgets in
390
\l{QStyle::}{sizeFromContents()} unless you have to; let the \l QCommonStyle
391
implementation handle it. If you make changes, keep them small. Application
392
development is difficult when the layout of widgets differs considerably
393
between styles.
394
395
Test your style with the \c -reverse command-line option, or with
396
\l QGuiApplication::setLayoutDirection(), so that asymmetric elements also
397
look correct in a right-to-left layout.
398
399
\sa QStyle, QStyleOption, QStylePainter, {Widget Style Reference},
400
{Styling a Checkbox: A Walkthrough}
401
*/
qtbase
src
widgets
doc
src
widgets-and-layouts
styles-drawing.qdoc
Generated on
for Qt by
1.16.1