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-checkbox-walkthrough.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-checkbox-walkthrough.html
6
\title Styling a Checkbox: A Walkthrough
7
\brief How a QCheckBox is drawn, from its paint event through QCommonStyle
8
to a custom indicator in a proxy style.
9
10
This page follows a checkbox from the moment it receives a paint event to
11
the moment the style finishes painting. It shows how the widget builds its
12
style option, how \l QCommonStyle breaks the element into parts, and how a
13
\l QProxyStyle replaces one of those parts. Most widgets follow the same
14
structure, so the same reading strategy works for them: find the style
15
option the widget builds, find the elements it draws, and read the
16
\l QCommonStyle implementation of those elements.
17
18
\section1 The widget builds a style option
19
20
\l QCheckBox uses \l QStyleOptionButton. Its \c initStyleOption() function
21
fills the option out like this, slightly simplified:
22
23
\snippet code/doc_src_styles.cpp 0
24
25
\l QStyleOption::initFrom() sets the information that every widget shares.
26
Its implementation amounts to this:
27
28
\snippet code/doc_src_styles.cpp 1
29
30
\c State_Enabled is set when the widget is enabled, \c State_HasFocus when
31
it has focus, \c State_KeyboardFocusChange when the user last changed focus
32
with the keyboard, and \c State_Active when the widget's window is the
33
active window. \c State_MouseOver is set while the mouse cursor is over the
34
widget. In addition to the state, \c initFrom() stores the layout direction,
35
the widget's rectangle, its palette, and its font metrics in the option.
36
37
\l QCheckBox then adds its own state. \c State_Sunken is set while the user
38
presses the box, whether it's checked or not. \c State_NoChange is set for a
39
partially checked tristate box; otherwise \c State_On or \c State_Off
40
reflects the check state. The option also carries the text, the icon, and
41
the icon size. \l QCheckBox keeps \c State_MouseOver only while the widget
42
has the \l{Qt::}{WA_Hover} attribute, which a style typically sets in
43
\l{QStyle::}{polish()}.
44
45
Suppose the user presses the checked checkbox in the following screenshot
46
with the mouse while it has focus. The screenshot also shows a radio button,
47
which uses the same structure with \c PE_IndicatorRadioButton and
48
\c CE_RadioButtonLabel:
49
50
\image styles/checkbox.webp
51
{Checkbox and radio button with their indicator, label, and focus
52
rectangles outlined and named in a legend}
53
54
At that moment, its option has these state flags:
55
56
\table 90%
57
\header
58
\li State flag
59
\li Set
60
\row
61
\li \c State_Sunken
62
\li Yes
63
\row
64
\li \c State_NoChange
65
\li No
66
\row
67
\li \c State_On
68
\li Yes
69
\row
70
\li \c State_Off
71
\li No
72
\row
73
\li \c State_MouseOver
74
\li Yes
75
\row
76
\li \c State_Enabled
77
\li Yes
78
\row
79
\li \c State_HasFocus
80
\li Yes
81
\row
82
\li \c State_KeyboardFocusChange
83
\li No
84
\row
85
\li \c State_Active
86
\li Yes
87
\endtable
88
89
\section1 The widget asks the style to draw
90
91
\l QCheckBox paints itself in \l{QWidget::}{paintEvent()} with a
92
\l QStylePainter, which wraps the drawing functions of \l QStyle:
93
94
\snippet code/doc_src_styles.cpp 2
95
96
That's all the widget does. Everything else happens in the style.
97
98
\section1 QCommonStyle breaks the element into parts
99
100
\l QCommonStyle handles \c CE_CheckBox by asking for the rectangles of its
101
two subelements, \c SE_CheckBoxIndicator and \c SE_CheckBoxContents, and
102
drawing an element into each. If the checkbox has focus, it also draws the
103
focus frame:
104
105
\snippet code/doc_src_styles.cpp 3
106
107
Note the \c proxy() calls. A style always draws its child elements through
108
\l{QStyle::}{proxy()} so that a \l QProxyStyle wrapped around it gets the
109
chance to override them.
110
111
\c CE_CheckBoxLabel is also implemented in \l QCommonStyle:
112
113
\snippet code/doc_src_styles.cpp 4
114
115
\l{QStyle::}{visualAlignment()} adjusts the alignment for the layout
116
direction. The style draws the icon, if there is one, and shrinks the
117
remaining text rectangle accordingly. \l{QStyle::}{drawItemText()} draws the
118
text with the alignment, the layout direction, and the mnemonic taken into
119
account, and it uses the palette to pick the text color. Drawing a label
120
involves many details, and the base class handles them well, so a custom
121
style rarely needs to reimplement it.
122
123
\section1 A proxy style replaces the indicator
124
125
The indicator, \c PE_IndicatorCheckBox, is where styles differ, so it's the
126
part to replace. The following \l QProxyStyle subclass draws a rounded
127
indicator from the palette colors in the option and forwards every other
128
element to the base style:
129
130
\snippet customstyle/checkboxstyle.cpp 0
131
132
\snippet customstyle/checkboxstyle.cpp 1
133
134
The implementation reads all of its information from the option. It picks
135
the color group from \c State_Enabled and \c State_Active, highlights the
136
frame while \c State_MouseOver is set, darkens the background while
137
\c State_Sunken is set, and draws a check mark for \c State_On or a filled
138
square for \c State_NoChange. Because every color comes from the palette,
139
the indicator follows the application palette and works in both light and
140
dark color schemes. It also saves and restores the painter, so the base
141
class finds the painter in the state it expects.
142
143
The same indicator appears wherever the style draws \c PE_IndicatorCheckBox:
144
in checkboxes, in checkable group boxes, and in item views that use it for
145
check marks. That reuse is the reason primitive elements exist.
146
147
To use the style, install it before the application creates its widgets:
148
149
\snippet customstyle/checkboxstyle.cpp 2
150
151
\section1 Apply the same reading to other widgets
152
153
To learn how a widget is drawn, you don't have to read all of the code. It's
154
usually enough to know which style elements the widget draws, which states
155
it sets, and what its style option contains. The widget builds an option and
156
calls the style one or more times; the style draws the elements the widget
157
asks for. \l{Widget Style Reference} lists exactly that for each widget.
158
159
\sa {How a Style Draws a Widget}, {Widget Style Reference}, QProxyStyle,
160
QStyleOptionButton
161
*/
qtbase
src
widgets
doc
src
widgets-and-layouts
styles-checkbox-walkthrough.qdoc
Generated on
for Qt by
1.16.1