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
qqstylekitcontrols.cpp
Go to the documentation of this file.
1// Copyright (C) 2025 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
8
10
11/*!
12 \qmltype AbstractStylableControls
13 \inqmlmodule Qt.labs.StyleKit
14 \brief Abstract base type containing the control types that can be styled.
15
16 AbstractControls is an abstract base type. It contains a \l ControlStyle for
17 each control type that can be styled by a \l Style, \l Theme, or \l StyleVariation.
18
19 The control types form a hierarchy where properties set on a base type
20 propagate down to the more specific ones. For example, assigning a radius
21 of four to \c abstractButton.background.radius will cause all button
22 types, such as \l button, \l checkBox, and \l radioButton, to get a radius
23 of four.
24
25 The snippets on this page illustrate a few of the key properties that can be
26 used to style each control type, but they are by no means exhaustive. Many other properties
27 are available, as documented in the \l ControlStyle and \l DelegateStyle documentation.
28 In practice, some of them can also be omitted because the
29 \l {Style::fallbackStyle}{fallback style} already supplies sensible defaults.
30 This means that if you simply remove a property from one of the snippets, it
31 might not actually affect its appearance, since it will just be read from the
32 fallback style instead.
33
34 \labs
35*/
36
37/*!
38 \qmlproperty ControlStyle AbstractStylableControls::control
39
40 Grouped property for styling all controls.
41
42 \c control is the base type in the control hierarchy, and properties set here
43 serve as defaults for all other control types. For example, setting
44 \c{control.implicitWidth: 200} makes \e all controls 200 pixels wide,
45 including buttons, scroll indicators and every other control.
46 It also overrides any values inherited from a higher level in the style
47 hierarchy (the \l Style for a \l Theme, or the
48 \l {Style::fallbackStyle}{fallbackStyle} for a \l Style), \e including hover
49 effects and other state-based behavior. Use \c{control} sparingly, and
50 prefer more specific base types like \l abstractButton or \l pane when
51 possible.
52
53 \snippet ControlsSnippets.qml control
54*/
55
56/*!
57 \qmlproperty ControlStyle AbstractStylableControls::abstractButton
58
59 Grouped property for styling all button-like controls, including
60 \l [QtQuickControls]{Button}, \l [QtQuickControls]{CheckBox},
61 \l [QtQuickControls]{RadioButton}, and \l [QtQuickControls]{Switch}.
62 Unset properties fall back to \l control.
63
64 \snippet ControlsSnippets.qml abstractButton
65
66 \sa {Qt Labs StyleKit}{Control Types}
67*/
68
69/*!
70 \qmlproperty ControlStyle AbstractStylableControls::applicationWindow
71
72 Grouped property for styling \l [QtQuickControls] ApplicationWindow.
73
74 Unset properties fall back to \l control.
75
76 Use \c applicationWindow to set the background color of the window:
77
78 \snippet ControlsSnippets.qml applicationWindow
79
80 \note The application needs to use ApplicationWindow, not Window, for this to take effect.
81*/
82
83/*!
84 \qmlproperty ControlStyle AbstractStylableControls::button
85
86 Grouped property for styling \l [QtQuickControls]{Button}.
87
88 Unset properties fall back to \l abstractButton.
89
90 \snippet ControlsSnippets.qml button
91*/
92
93/*!
94 \qmlproperty ControlStyle AbstractStylableControls::checkBox
95
96 Grouped property for styling \l [QtQuickControls]{CheckBox}.
97
98 Unset properties fall back to \l abstractButton.
99
100 \snippet ControlsSnippets.qml checkBox
101*/
102
103/*!
104 \qmlproperty ControlStyle AbstractStylableControls::comboBox
105
106 Grouped property for styling \l [QtQuickControls]{ComboBox}.
107
108 Unset properties fall back to \l control.
109
110 \snippet ControlsSnippets.qml comboBox
111*/
112
113/*!
114 \qmlproperty ControlStyle AbstractStylableControls::flatButton
115
116 Grouped property for styling flat buttons (buttons with no visible
117 background in their normal state). The styling will take effect for
118 a \l [QtQuickControls]{Button} if \l [QtQuickControls]{Button::flat}{Button.flat} is set to \c true.
119
120 Unset properties fall back to \l abstractButton.
121
122 \snippet ControlsSnippets.qml flatButton
123*/
124
125/*!
126 \qmlproperty ControlStyle AbstractStylableControls::frame
127
128 Grouped property for styling \l [QtQuickControls]{Frame}.
129
130 Unset properties fall back to \l pane.
131
132 \snippet ControlsSnippets.qml frame
133*/
134
135/*!
136 \qmlproperty ControlStyle AbstractStylableControls::groupBox
137
138 Grouped property for styling \l [QtQuickControls]{GroupBox}.
139
140 Unset properties fall back to \l frame.
141
142 \snippet ControlsSnippets.qml groupBox
143*/
144
145/*!
146 \qmlproperty ControlStyle AbstractStylableControls::itemDelegate
147
148 Grouped property for styling \l [QtQuickControls]{ItemDelegate}.
149
150 Unset properties fall back to \l control.
151
152 \note In Qt Quick Controls, \l [QtQuickControls]{ItemDelegate} inherits from
153 \l [QtQuickControls]{AbstractButton}. In StyleKit, however, \c itemDelegate
154 falls back to \l control rather than \l abstractButton, since delegates are
155 typically \e styled very differently from buttons (flat, no borders or drop shadows, etc.).
156
157 \snippet ControlsSnippets.qml itemDelegate
158*/
159
160/*!
161 \qmlproperty ControlStyle AbstractStylableControls::label
162
163 Grouped property for styling \l [QtQuickControls]{Label}.
164
165 Unset properties fall back to \l control.
166
167 \snippet ControlsSnippets.qml label
168*/
169
170/*!
171 \qmlproperty ControlStyle AbstractStylableControls::page
172
173 Grouped property for styling \l [QtQuickControls]{Page}.
174
175 Unset properties fall back to \l pane.
176
177 \snippet ControlsSnippets.qml page
178*/
179
180/*!
181 \qmlproperty ControlStyle AbstractStylableControls::pane
182
183 Grouped property for styling \l [QtQuickControls]{Pane}.
184
185 Unset properties fall back to \l control.
186
187 \snippet ControlsSnippets.qml pane
188*/
189
190/*!
191 \qmlproperty ControlStyle AbstractStylableControls::popup
192
193 Grouped property for styling \l [QtQuickControls]{Popup}.
194
195 Unset properties fall back to \l control.
196
197 \snippet ControlsSnippets.qml popup
198*/
199
200/*!
201 \qmlproperty ControlStyle AbstractStylableControls::progressBar
202
203 Grouped property for styling \l [QtQuickControls]{ProgressBar}.
204 For a progress bar, the groove is styled through the indicator, while the progress
205 track is styled through the indicator's foreground.
206
207 Unset properties fall back to \l control.
208
209 \snippet ControlsSnippets.qml progressBar
210
211 StyleKit doesn't provide a dedicated property to style the indeterminate animation
212 of a progress bar. To change the animation, you need to implement a custom indicator
213 foreground \l {DelegateStyle::}{delegate} instead:
214
215 \snippet ControlsSnippets.qml progressBar indeterminate
216*/
217
218/*!
219 \qmlproperty ControlStyle AbstractStylableControls::radioButton
220
221 Grouped property for styling \l [QtQuickControls]{RadioButton}.
222
223 Unset properties fall back to \l abstractButton.
224
225 \snippet ControlsSnippets.qml radioButton
226*/
227
228/*!
229 \qmlproperty ControlStyle AbstractStylableControls::scrollBar
230
231 Grouped property for styling \l [QtQuickControls]{ScrollBar}.
232 For a scroll bar, the groove is styled through the indicator, while the handle is
233 styled through the indicator's foreground.
234
235 Unset properties fall back to \l control.
236
237 \snippet ControlsSnippets.qml scrollBar
238*/
239
240/*!
241 \qmlproperty ControlStyle AbstractStylableControls::scrollIndicator
242
243 Grouped property for styling \l [QtQuickControls]{ScrollIndicator}.
244
245 Unset properties fall back to \l control.
246
247 \snippet ControlsSnippets.qml scrollIndicator
248*/
249
250/*!
251 \qmlproperty ControlStyle AbstractStylableControls::scrollView
252
253 Grouped property for styling \l [QtQuickControls]{ScrollView}.
254
255 ScrollView itself has no visual delegates to style. Its scroll bars can be
256 styled separately through the \l scrollBar property. But you can use
257 \l {ControlStateStyle::padding}{padding} to control the space between
258 the scroll bars and the content area.
259
260 Unset properties fall back to \l control.
261
262 \snippet ControlsSnippets.qml scrollView
263*/
264
265/*!
266 \qmlproperty ControlStyle AbstractStylableControls::slider
267
268 Grouped property for styling \l [QtQuickControls]{Slider}.
269 For a slider bar, the groove is styled through the indicator, while the progress
270 track is styled through the indicator's foreground.
271 Unset properties fall back to \l control.
272
273 \snippet ControlsSnippets.qml slider
274*/
275
276/*!
277 \qmlproperty ControlStyle AbstractStylableControls::spinBox
278
279 Grouped property for styling \l [QtQuickControls]{SpinBox}.
280
281 Unset properties fall back to \l control.
282
283 \snippet ControlsSnippets.qml spinBox
284
285 \note It's currently only possible to position the up and down buttons to
286 be on the left or right side of the control, but not on top of each other.
287*/
288
289/*!
290 \qmlproperty ControlStyle AbstractStylableControls::switchControl
291
292 Grouped property for styling \l [QtQuickControls]{Switch}.
293
294 Unset properties fall back to \l abstractButton.
295
296 \snippet ControlsSnippets.qml switchControl
297*/
298
299/*!
300 \qmlproperty ControlStyle AbstractStylableControls::tabBar
301
302 Grouped property for styling \l [QtQuickControls]{TabBar}.
303
304 Unset properties fall back to \l pane.
305
306 \snippet ControlsSnippets.qml tabBar
307*/
308
309/*!
310 \qmlproperty ControlStyle AbstractStylableControls::tabButton
311
312 Grouped property for styling \l [QtQuickControls]{TabButton}.
313
314 Unset properties fall back to \l abstractButton.
315
316 \snippet ControlsSnippets.qml tabButton
317*/
318
319/*!
320 \qmlproperty ControlStyle AbstractStylableControls::textArea
321
322 Grouped property for styling \l [QtQuickControls]{TextArea}.
323
324 Unset properties fall back to \l textInput.
325
326 \snippet ControlsSnippets.qml textArea
327*/
328
329/*!
330 \qmlproperty ControlStyle AbstractStylableControls::textField
331
332 Grouped property for styling \l [QtQuickControls]{TextField}.
333
334 Unset properties fall back to \l textInput.
335
336 \snippet ControlsSnippets.qml textField
337*/
338
339/*!
340 \qmlproperty ControlStyle AbstractStylableControls::textInput
341
342 Grouped property for styling all text input controls, including
343 \l [QtQuickControls]{TextField} and \l [QtQuickControls]{TextArea}.
344
345 Unset properties fall back to \l control.
346
347 \snippet ControlsSnippets.qml textInput
348*/
349
350/*!
351 \qmlproperty ControlStyle AbstractStylableControls::toolBar
352
353 Grouped property for styling \l [QtQuickControls]{ToolBar}.
354
355 Unset properties fall back to \l pane.
356
357 \snippet ControlsSnippets.qml toolBar
358*/
359
360/*!
361 \qmlproperty ControlStyle AbstractStylableControls::toolButton
362
363 Grouped property for styling \l [QtQuickControls]{ToolButton}.
364
365 Unset properties fall back to \l abstractButton.
366
367 \snippet ControlsSnippets.qml toolButton
368*/
369
370/*!
371 \qmlproperty ControlStyle AbstractStylableControls::toolSeparator
372
373 Grouped property for styling \l [QtQuickControls]{ToolSeparator}.
374
375 Unset properties fall back to \l control.
376
377 \snippet ControlsSnippets.qml toolSeparator
378*/
379
380using namespace Qt::StringLiterals;
381
382QQStyleKitControls::QQStyleKitControls(QObject *parent)
383 : QObject(parent)
384{
385}
386
388{
389 return QQmlListProperty<QObject>(this, &m_data);
390}
391
393{
394 return m_data;
395}
396
397/* Lazy-create the controls that the style is actually using, when accessed
398 * them from the style/application (e.g from Style or Theme). We don't lazy
399 * create any controls while resolving style properties, as undefined controls would
400 * anyway not contain any property overrides. The properties have setters too, to
401 * allow the style/application to share custom ControlStyle the classical
402 * way, e.g button: ControlStyle { id: button }. */
403QQStyleKitControl* QQStyleKitControls::getControl(QQStyleKitExtendableControlType controlType) const
404{
405 if (!m_controls.contains(controlType))
406 return nullptr;
407 return m_controls[controlType];
408}
409
410
412{
413 QList<QQStyleKitVariation *> list;
414 for (auto *obj : children()) {
415 if (auto *variation = qobject_cast<QQStyleKitVariation *>(obj))
416 list.append(variation);
417 }
418 return list;
419}
420
421#define IMPLEMENT_ACCESSORS(NAME, TYPE) QQStyleKitControl
422 *QQStyleKitControls::NAME() const \
423{
424 if (!m_controls.contains(TYPE)) {
425 auto *self = const_cast<QQStyleKitControls *>(this);
426 auto *control = new QQStyleKitControl(self);
427 self->m_controls.insert(TYPE, control);
428 }
429 return m_controls[TYPE]; \
430}void
431 QQStyleKitControls::set_ ## NAME(QQStyleKitControl *control) \
432{
433 m_controls.insert(TYPE, control); \
434}
435
436
437IMPLEMENT_ACCESSORS(abstractButton, QQStyleKitReader::ControlType::AbstractButton)
438IMPLEMENT_ACCESSORS(applicationWindow, QQStyleKitReader::ControlType::ApplicationWindow)
439IMPLEMENT_ACCESSORS(control, QQStyleKitReader::ControlType::Control)
440IMPLEMENT_ACCESSORS(button, QQStyleKitReader::ControlType::Button)
441IMPLEMENT_ACCESSORS(flatButton, QQStyleKitReader::ControlType::FlatButton)
442IMPLEMENT_ACCESSORS(checkBox, QQStyleKitReader::ControlType::CheckBox)
443IMPLEMENT_ACCESSORS(comboBox, QQStyleKitReader::ControlType::ComboBox)
444IMPLEMENT_ACCESSORS(progressBar, QQStyleKitReader::ControlType::ProgressBar)
445IMPLEMENT_ACCESSORS(scrollBar, QQStyleKitReader::ControlType::ScrollBar)
446IMPLEMENT_ACCESSORS(scrollIndicator, QQStyleKitReader::ControlType::ScrollIndicator)
447IMPLEMENT_ACCESSORS(scrollView, QQStyleKitReader::ControlType::ScrollView)
448IMPLEMENT_ACCESSORS(slider, QQStyleKitReader::ControlType::Slider)
449IMPLEMENT_ACCESSORS(spinBox, QQStyleKitReader::ControlType::SpinBox)
450IMPLEMENT_ACCESSORS(switchControl, QQStyleKitReader::ControlType::SwitchControl)
451IMPLEMENT_ACCESSORS(tabBar, QQStyleKitReader::ControlType::TabBar)
452IMPLEMENT_ACCESSORS(tabButton, QQStyleKitReader::ControlType::TabButton)
453IMPLEMENT_ACCESSORS(textField, QQStyleKitReader::ControlType::TextField)
454IMPLEMENT_ACCESSORS(textInput, QQStyleKitReader::ControlType::TextInput)
455IMPLEMENT_ACCESSORS(toolBar, QQStyleKitReader::ControlType::ToolBar)
456IMPLEMENT_ACCESSORS(toolButton, QQStyleKitReader::ControlType::ToolButton)
457IMPLEMENT_ACCESSORS(toolSeparator, QQStyleKitReader::ControlType::ToolSeparator)
458IMPLEMENT_ACCESSORS(radioButton, QQStyleKitReader::ControlType::RadioButton)
459IMPLEMENT_ACCESSORS(itemDelegate, QQStyleKitReader::ControlType::ItemDelegate)
460IMPLEMENT_ACCESSORS(popup, QQStyleKitReader::ControlType::Popup)
461IMPLEMENT_ACCESSORS(pane, QQStyleKitReader::ControlType::Pane)
462IMPLEMENT_ACCESSORS(page, QQStyleKitReader::ControlType::Page)
463IMPLEMENT_ACCESSORS(frame, QQStyleKitReader::ControlType::Frame)
464IMPLEMENT_ACCESSORS(label, QQStyleKitReader::ControlType::Label)
465IMPLEMENT_ACCESSORS(groupBox, QQStyleKitReader::ControlType::GroupBox)
466IMPLEMENT_ACCESSORS(textArea, QQStyleKitReader::ControlType::TextArea)
467
468#undef IMPLEMENT_ACCESSORS
469
471{
472 for (auto *obj : children()) {
473 if (auto *customControl = qobject_cast<QQStyleKitCustomControl *>(obj)) {
474 const QQStyleKitExtendableControlType type = customControl->controlType();
475 const QQStyleKitExtendableControlType reserved
476 = QQStyleKitExtendableControlType(QQStyleKitReader::ControlType::Unspecified);
477 if (type >= reserved)
478 qmlWarning(this) << "CustomControls must use a controlType less than " << reserved;
479 if (m_controls.contains(type))
480 qmlWarning(this) << "CustomControl registered more than once: " << type;
481 m_controls.insert(type, customControl);
482 }
483 }
484}
485
486QT_END_NAMESPACE
487
488#include "moc_qqstylekitcontrols_p.cpp"
void componentComplete() override
Invoked after the root component that caused this instantiation has completed construction.
const QList< QObject * > children() const
QList< QQStyleKitVariation * > variations() const
QQmlListProperty< QObject > data()
Combined button and popup list for selecting options.
#define IMPLEMENT_ACCESSORS(NAME, TYPE)