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 {qtlabsstylekit-controls.html}{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 \l padding
257 to control the space between the scroll bars and the content area.
258
259 Unset properties fall back to \l control.
260
261 \snippet ControlsSnippets.qml scrollView
262*/
263
264/*!
265 \qmlproperty ControlStyle AbstractStylableControls::slider
266
267 Grouped property for styling \l [QtQuickControls]{Slider}.
268 For a slider bar, the groove is styled through the indicator, while the progress
269 track is styled through the indicator's foreground.
270 Unset properties fall back to \l control.
271
272 \snippet ControlsSnippets.qml slider
273*/
274
275/*!
276 \qmlproperty ControlStyle AbstractStylableControls::spinBox
277
278 Grouped property for styling \l [QtQuickControls]{SpinBox}.
279
280 Unset properties fall back to \l control.
281
282 \snippet ControlsSnippets.qml spinBox
283
284 \note It's currently only possible to position the up and down buttons to
285 be on the left or right side of the control, but not on top of each other.
286*/
287
288/*!
289 \qmlproperty ControlStyle AbstractStylableControls::switchControl
290
291 Grouped property for styling \l [QtQuickControls]{Switch}.
292
293 Unset properties fall back to \l abstractButton.
294
295 \snippet ControlsSnippets.qml switchControl
296*/
297
298/*!
299 \qmlproperty ControlStyle AbstractStylableControls::tabBar
300
301 Grouped property for styling \l [QtQuickControls]{TabBar}.
302
303 Unset properties fall back to \l pane.
304
305 \snippet ControlsSnippets.qml tabBar
306*/
307
308/*!
309 \qmlproperty ControlStyle AbstractStylableControls::tabButton
310
311 Grouped property for styling \l [QtQuickControls]{TabButton}.
312
313 Unset properties fall back to \l abstractButton.
314
315 \snippet ControlsSnippets.qml tabButton
316*/
317
318/*!
319 \qmlproperty ControlStyle AbstractStylableControls::textArea
320
321 Grouped property for styling \l [QtQuickControls]{TextArea}.
322
323 Unset properties fall back to \l textInput.
324
325 \snippet ControlsSnippets.qml textArea
326*/
327
328/*!
329 \qmlproperty ControlStyle AbstractStylableControls::textField
330
331 Grouped property for styling \l [QtQuickControls]{TextField}.
332
333 Unset properties fall back to \l textInput.
334
335 \snippet ControlsSnippets.qml textField
336*/
337
338/*!
339 \qmlproperty ControlStyle AbstractStylableControls::textInput
340
341 Grouped property for styling all text input controls, including
342 \l [QtQuickControls]{TextField} and \l [QtQuickControls]{TextArea}.
343
344 Unset properties fall back to \l control.
345
346 \snippet ControlsSnippets.qml textInput
347*/
348
349/*!
350 \qmlproperty ControlStyle AbstractStylableControls::toolBar
351
352 Grouped property for styling \l [QtQuickControls]{ToolBar}.
353
354 Unset properties fall back to \l pane.
355
356 \snippet ControlsSnippets.qml toolBar
357*/
358
359/*!
360 \qmlproperty ControlStyle AbstractStylableControls::toolButton
361
362 Grouped property for styling \l [QtQuickControls]{ToolButton}.
363
364 Unset properties fall back to \l abstractButton.
365
366 \snippet ControlsSnippets.qml toolButton
367*/
368
369/*!
370 \qmlproperty ControlStyle AbstractStylableControls::toolSeparator
371
372 Grouped property for styling \l [QtQuickControls]{ToolSeparator}.
373
374 Unset properties fall back to \l control.
375
376 \snippet ControlsSnippets.qml toolSeparator
377*/
378
379using namespace Qt::StringLiterals;
380
381QQStyleKitControls::QQStyleKitControls(QObject *parent)
382 : QObject(parent)
383{
384}
385
387{
388 return QQmlListProperty<QObject>(this, &m_data);
389}
390
392{
393 return m_data;
394}
395
396/* Lazy-create the controls that the style is actually using, when accessed
397 * them from the style/application (e.g from Style or Theme). We don't lazy
398 * create any controls while resolving style properties, as undefined controls would
399 * anyway not contain any property overrides. The properties have setters too, to
400 * allow the style/application to share custom ControlStyle the classical
401 * way, e.g button: ControlStyle { id: button }. */
402QQStyleKitControl* QQStyleKitControls::getControl(QQStyleKitExtendableControlType controlType) const
403{
404 if (!m_controls.contains(controlType))
405 return nullptr;
406 return m_controls[controlType];
407}
408
409
411{
412 QList<QQStyleKitVariation *> list;
413 for (auto *obj : children()) {
414 if (auto *variation = qobject_cast<QQStyleKitVariation *>(obj))
415 list.append(variation);
416 }
417 return list;
418}
419
420#define IMPLEMENT_ACCESSORS(NAME, TYPE) QQStyleKitControl
421 *QQStyleKitControls::NAME() const \
422{
423 if (!m_controls.contains(TYPE)) {
424 auto *self = const_cast<QQStyleKitControls *>(this);
425 auto *control = new QQStyleKitControl(self);
426 self->m_controls.insert(TYPE, control);
427 }
428 return m_controls[TYPE]; \
429}void
430 QQStyleKitControls::set_ ## NAME(QQStyleKitControl *control) \
431{
432 m_controls.insert(TYPE, control); \
433}
434
435
436IMPLEMENT_ACCESSORS(abstractButton, QQStyleKitReader::ControlType::AbstractButton)
437IMPLEMENT_ACCESSORS(applicationWindow, QQStyleKitReader::ControlType::ApplicationWindow)
438IMPLEMENT_ACCESSORS(control, QQStyleKitReader::ControlType::Control)
439IMPLEMENT_ACCESSORS(button, QQStyleKitReader::ControlType::Button)
440IMPLEMENT_ACCESSORS(flatButton, QQStyleKitReader::ControlType::FlatButton)
441IMPLEMENT_ACCESSORS(checkBox, QQStyleKitReader::ControlType::CheckBox)
442IMPLEMENT_ACCESSORS(comboBox, QQStyleKitReader::ControlType::ComboBox)
443IMPLEMENT_ACCESSORS(progressBar, QQStyleKitReader::ControlType::ProgressBar)
444IMPLEMENT_ACCESSORS(scrollBar, QQStyleKitReader::ControlType::ScrollBar)
445IMPLEMENT_ACCESSORS(scrollIndicator, QQStyleKitReader::ControlType::ScrollIndicator)
446IMPLEMENT_ACCESSORS(scrollView, QQStyleKitReader::ControlType::ScrollView)
447IMPLEMENT_ACCESSORS(slider, QQStyleKitReader::ControlType::Slider)
448IMPLEMENT_ACCESSORS(spinBox, QQStyleKitReader::ControlType::SpinBox)
449IMPLEMENT_ACCESSORS(switchControl, QQStyleKitReader::ControlType::SwitchControl)
450IMPLEMENT_ACCESSORS(tabBar, QQStyleKitReader::ControlType::TabBar)
451IMPLEMENT_ACCESSORS(tabButton, QQStyleKitReader::ControlType::TabButton)
452IMPLEMENT_ACCESSORS(textField, QQStyleKitReader::ControlType::TextField)
453IMPLEMENT_ACCESSORS(textInput, QQStyleKitReader::ControlType::TextInput)
454IMPLEMENT_ACCESSORS(toolBar, QQStyleKitReader::ControlType::ToolBar)
455IMPLEMENT_ACCESSORS(toolButton, QQStyleKitReader::ControlType::ToolButton)
456IMPLEMENT_ACCESSORS(toolSeparator, QQStyleKitReader::ControlType::ToolSeparator)
457IMPLEMENT_ACCESSORS(radioButton, QQStyleKitReader::ControlType::RadioButton)
458IMPLEMENT_ACCESSORS(itemDelegate, QQStyleKitReader::ControlType::ItemDelegate)
459IMPLEMENT_ACCESSORS(popup, QQStyleKitReader::ControlType::Popup)
460IMPLEMENT_ACCESSORS(pane, QQStyleKitReader::ControlType::Pane)
461IMPLEMENT_ACCESSORS(page, QQStyleKitReader::ControlType::Page)
462IMPLEMENT_ACCESSORS(frame, QQStyleKitReader::ControlType::Frame)
463IMPLEMENT_ACCESSORS(label, QQStyleKitReader::ControlType::Label)
464IMPLEMENT_ACCESSORS(groupBox, QQStyleKitReader::ControlType::GroupBox)
465IMPLEMENT_ACCESSORS(textArea, QQStyleKitReader::ControlType::TextArea)
466
467#undef IMPLEMENT_ACCESSORS
468
470{
471 for (auto *obj : children()) {
472 if (auto *customControl = qobject_cast<QQStyleKitCustomControl *>(obj)) {
473 const QQStyleKitExtendableControlType type = customControl->controlType();
474 const QQStyleKitExtendableControlType reserved
475 = QQStyleKitExtendableControlType(QQStyleKitReader::ControlType::Unspecified);
476 if (type >= reserved)
477 qmlWarning(this) << "CustomControls must use a controlType less than " << reserved;
478 if (m_controls.contains(type))
479 qmlWarning(this) << "CustomControl registered more than once: " << type;
480 m_controls.insert(type, customControl);
481 }
482 }
483}
484
485QT_END_NAMESPACE
486
487#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)