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