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
qtlabsstylekit-propagation.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 qtlabsstylekit-propagation.html
6
\title StyleKit Property Resolution
7
\brief How StyleKit resolves style property values.
8
9
A style property — such as \l {DelegateStyle::color}{background.color} — can have
10
many different values depending on the control's \l {StyleReader}{state}, the active \l Theme, and
11
effective \l {StyleVariation}{style variations}.
12
For example, it can differ between the \l {ControlStateStyle::}{pressed} and
13
\l {ControlStateStyle::}{hovered} states, or between the \l {Style::light}{light}
14
and \l {Style::dark}{dark} themes.
15
This document details how \c StyleKit resolves the value a property will get when
16
used for styling a particular \l [QtQuickControls]{Control}.
17
18
\section1 Control States
19
20
Controls change appearance depending on interaction —
21
\l {ControlStateStyle::}{hovered}, \l {ControlStateStyle::}{pressed},
22
\l {ControlStateStyle::}{checked}, \l {ControlStateStyle::}{focused},
23
\l {ControlStateStyle::}{disabled}, and so on. When resolving a property, \c StyleKit exhausts all
24
state-specific values first, before checking the normal state.
25
26
For example, if a \l [QtQuickControls]{Button} is \l {ControlStateStyle::}{hovered},
27
\c {hovered.button.background.color} is checked before \c {button.background.color}.
28
And if it's also \l {ControlStateStyle::}{pressed}, \c {pressed.button.background.color}
29
is checked before them both. The order of precedence between states is documented in
30
the \l {ControlStateStyle}{ControlStateStyle documentation}.
31
32
States can also be nested. A combination such as \c {pressed.hovered.button.background.color}
33
is more specific than either \c {pressed.button.background.color} or \c {hovered.button.background.color}
34
alone, and takes precedence over both.
35
36
\section1 Fallback Properties
37
38
Some style properties can be set more than one way. For example, the top-left radius
39
on the background can be set either directly using
40
\l {DelegateStyle::topLeftRadius}{background.topLeftRadius}, or
41
indirectly using \l {DelegateStyle::radius}{background.radius} (which sets all corners
42
to the same radius). For such properties, \c StyleKit checks the specific property
43
first, then the fallback, and exhausts both within the current state before moving to
44
a less specific state. For example, \c {button.hovered.background.radius} takes
45
precedence over \c {button.background.topLeftRadius}, if the control is hovered.
46
And of course, \c {button.hovered.background.topLeftRadius} takes precedence over both.
47
48
\section1 Control Type Hierarchy
49
50
\l {AbstractStylableControls}{The controls} form a hierarchy. A \l {AbstractStylableControls::button}{button}
51
falls back to \l {AbstractStylableControls::abstractButton}{abstractButton}, which
52
falls back to \l {AbstractStylableControls::control}{control}.
53
A \l {AbstractStylableControls::groupBox}{groupBox} falls back to
54
\l {AbstractStylableControls::frame}{frame}, which falls back to
55
\l {AbstractStylableControls::pane}{pane}, which falls back to
56
\l {AbstractStylableControls::control}{control}, and so on.
57
\c control is the root type in the hierarchy, mirroring the type
58
hierarchy of \l {Qt Quick Controls}. Refer to the \l {AbstractStylableControls}{documentation}
59
for each control type to see its direct fallback type.
60
61
When all states and fallback properties have been exhausted for a specific control type,
62
\c StyleKit walks up the hierarchy to check whether it is set in a base type.
63
For example, if \c {button.background.color} is not set, \c StyleKit will check
64
\c {abstractButton.background.color} instead, and so on.
65
This motivates the designer to factor the property values that are common across multiple
66
controls into a common base type, to maximize reuse and minimize duplication. For example, you
67
can put all the property values common to buttons, checkboxes, and radio buttons in
68
\c abstractButton, and only set the properties that differ in the specific subtypes.
69
70
Note that any state (including the normal state) in a more specific type takes precedence over
71
any state in a base type. For example, \c {button.background.color} takes
72
precedence over \c {hovered.abstractButton.background.color}, even if the control is hovered.
73
And of course, \c {hovered.button.background.color} takes precedence over both.
74
75
\section1 Style And Theme
76
77
The \l {Control Type Hierarchy} is repeated inside both a \l Style and a \l Theme.
78
When resolving a property, \c StyleKit first looks through the control type hierarchy in
79
the active \l Theme, then in the active \l Style.
80
This means that properties set in the active theme take precedence over those set in the style.
81
As a consequence, a base type in the theme also overrides a more specific type in the style. For
82
example, \c {theme.control.background.color} takes precedence over \c {style.button.background.color}.
83
84
\section1 Style Variations
85
86
The \l {Control Type Hierarchy} is repeated inside a \l StyleVariation.
87
Style variations can be defined both in a style and in a theme, and a style variation in a theme
88
takes precedence over the theme itself. Since a theme takes precedence over a style, the style
89
properties in the current theme will also take precedence over style variations in the style.
90
For example, \c {theme.button.background.color} takes precedence over
91
\c {style.variation.button.background.color}.
92
93
\section1 Fallback Style
94
95
Every \l Style has a \l {Style::fallbackStyle}{fallback style} — a complete style
96
that acts as a last resort when a property cannot be resolved within the active style.
97
If the full resolution process (across control types, states, the active theme, and any
98
style variations) fails to find a value, \c StyleKit repeats the entire process in the
99
fallback style. The default fallback style looks similar to the \l {Basic Style}, so even
100
an empty style will still produce fully styled controls.
101
102
The fallback style can itself have a fallback style, and \c StyleKit follows this chain
103
recursively until it either finds a value or exhausts the chain. If no value is found, a
104
default value is used.
105
106
\section1 Putting It All Together
107
108
As an example, let's say \c StyleKit needs to resolve \c {background.color} for a
109
\l {ControlStateStyle::}{hovered} \l [QtQuickControls]{Button}. The style has a theme, and both
110
the style and the theme have an active variation. \c StyleKit then checks the following locations
111
in order, using the first value it finds:
112
113
\list
114
\li \c {theme.variation.hovered.button.background.color}
115
\li \c {theme.variation.button.background.color}
116
\li \c {theme.variation.hovered.abstractButton.background.color}
117
\li \c {theme.variation.abstractButton.background.color}
118
\li \c {theme.variation.hovered.control.background.color}
119
\li \c {theme.variation.control.background.color}
120
\li \c {theme.hovered.button.background.color}
121
\li \c {theme.button.background.color}
122
\li \c {theme.hovered.abstractButton.background.color}
123
\li \c {theme.abstractButton.background.color}
124
\li \c {theme.hovered.control.background.color}
125
\li \c {theme.control.background.color}
126
\li \c {style.variation.hovered.button.background.color}
127
\li \c {style.variation.button.background.color}
128
\li \c {style.variation.hovered.abstractButton.background.color}
129
\li \c {style.variation.abstractButton.background.color}
130
\li \c {style.variation.hovered.control.background.color}
131
\li \c {style.variation.control.background.color}
132
\li \c {style.hovered.button.background.color}
133
\li \c {style.button.background.color}
134
\li \c {style.hovered.abstractButton.background.color}
135
\li \c {style.abstractButton.background.color}
136
\li \c {style.hovered.control.background.color}
137
\li \c {style.control.background.color}
138
\endlist
139
140
If all these locations are exhausted without finding a value, the same process is
141
repeated in the fallback style (recursively, if the fallback style also has a fallback
142
style). If still not found, a default value is used.
143
144
\section1 Debugging Property Resolution
145
146
With multiple control types, themes, variations, and fallback styles all
147
contributing to the final value of a property, it can sometimes be hard to
148
tell why a particular control ends up with a particular appearance.
149
\l StyleKitDebug is a diagnostic in-app tool that logs each style property
150
read to the debug output, showing exactly which layer and control type a
151
property was resolved from.
152
153
To start tracing, assign the control you want to introspect to the
154
\l {StyleKitDebug::control}{StyleKit.debug.control} property:
155
156
\snippet StyleKitDebug.qml trace
157
158
Each resolved property is printed as a single line, for example:
159
160
\code
161
[read] StyleReader[Hovered].button.background.color -> Style.Theme(Dark).button[Hovered] = #add8e6
162
\endcode
163
164
The \c StyleReader in the output refers to the \l StyleReader that the \l Button
165
uses internally to read its style property values.
166
167
Use the \l {StyleKitDebug::filter}{filter} property to limit the output to properties of interest.
168
169
\note Enabling \l StyleKitDebug will severely degrade performance. Use it
170
only during debugging.
171
172
\sa Style, Theme, StyleVariation, StyleKitDebug, {StyleKit Features Overview}
173
*/
qtdeclarative
src
labs
stylekit
doc
src
qtlabsstylekit-propagation.qdoc
Generated on
for Qt by
1.16.1