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.width: 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::checkDelegate
107
108 Grouped property for styling \l [QtQuickControls]{CheckDelegate}.
109
110 Unset properties fall back to \l itemDelegate.
111
112 \snippet ControlsSnippets.qml checkDelegate
113*/
114
115/*!
116 \qmlproperty ControlStyle AbstractStylableControls::comboBox
117
118 Grouped property for styling \l [QtQuickControls]{ComboBox}.
119
120 Unset properties fall back to \l control.
121
122 \note Style the popup through \l popup, and its items through \l itemDelegate.
123
124 \snippet ControlsSnippets.qml comboBox
125*/
126
127/*!
128 \qmlproperty ControlStyle AbstractStylableControls::flatButton
129
130 Grouped property for styling flat buttons (buttons with no visible
131 background in their normal state). The styling will take effect for
132 a \l [QtQuickControls]{Button} if \l [QtQuickControls]{Button::flat}{Button.flat} is set to \c true.
133
134 Unset properties fall back to \l abstractButton.
135
136 \snippet ControlsSnippets.qml flatButton
137*/
138
139/*!
140 \qmlproperty ControlStyle AbstractStylableControls::frame
141
142 Grouped property for styling \l [QtQuickControls]{Frame}.
143
144 Unset properties fall back to \l pane.
145
146 \snippet ControlsSnippets.qml frame
147*/
148
149/*!
150 \qmlproperty ControlStyle AbstractStylableControls::groupBox
151
152 Grouped property for styling \l [QtQuickControls]{GroupBox}.
153
154 Unset properties fall back to \l frame.
155
156 \snippet ControlsSnippets.qml groupBox
157*/
158
159/*!
160 \qmlproperty ControlStyle AbstractStylableControls::itemDelegate
161
162 Grouped property for styling \l [QtQuickControls]{ItemDelegate}.
163
164 Unset properties fall back to \l control.
165
166 \note In Qt Quick Controls, \l [QtQuickControls]{ItemDelegate} inherits from
167 \l [QtQuickControls]{AbstractButton}. In StyleKit, however, \c itemDelegate
168 falls back to \l control rather than \l abstractButton, since delegates are
169 typically \e styled very differently from buttons (flat, no borders or drop shadows, etc.).
170
171 \snippet ControlsSnippets.qml itemDelegate
172*/
173
174/*!
175 \qmlproperty ControlStyle AbstractStylableControls::label
176
177 Grouped property for styling \l [QtQuickControls]{Label}.
178
179 Unset properties fall back to \l control.
180
181 \snippet ControlsSnippets.qml label
182*/
183
184/*!
185 \qmlproperty ControlStyle AbstractStylableControls::menu
186
187 Grouped property for styling \l [QtQuickControls]{Menu}.
188
189 Unset properties fall back to \l popup.
190
191 \snippet ControlsSnippets.qml menu
192*/
193
194/*
195 \qmlproperty ControlStyle AbstractStylableControls::menuItem
196
197 Grouped property for styling \l [QtQuickControls]{MenuItem}.
198
199 Unset properties fall back to \l control.
200
201 \note In Qt Quick Controls, a \l [QtQuickControls]{MenuItem} inherits from
202    \l [QtQuickControls]{AbstractButton}. In StyleKit, however, \c menuItem
203 falls back to \l control instead of \l abstractButton, since menu items are
204 typically \e styled very differently from regular buttons
205 (flat, no borders or drop shadows, etc.).
206
207 \snippet ControlsSnippets.qml menuItem
208*/
209
210/*!
211 \qmlproperty ControlStyle AbstractStylableControls::menuBar
212
213 Grouped property for styling \l [QtQuickControls]{MenuBar}.
214
215 Unset properties fall back to \l control.
216
217 \note Styling \l [QtQuickControls]{MenuBar}, \l [QtQuickControls]{MenuBarItem},
218 and \l [QtQuickControls]{MenuSeparator} normally only affects non-native
219 menu bars. When a MenuBar is implemented as a native menu bar, its delegates
220 are not used for rendering, so StyleKit style properties may have no visual
221 effect. See \l {MenuBar QML Type} {Native Menu Bars} for details.
222
223 \snippet ControlsSnippets.qml menuBar
224*/
225
226/*
227 \qmlproperty ControlStyle AbstractStylableControls::menuBarItem
228
229 Grouped property for styling menu items in a \l [QtQuickControls]{MenuBar}.
230
231 Unset properties fall back to \l control.
232
233 \note In Qt Quick Controls, a \l [QtQuickControls]{MenuBarItem} inherits from
234 \l [QtQuickControls]{AbstractButton}. In StyleKit, however, \c menuBarItem is a
235 separate control type that falls back to \l control instead of \l abstractButton,
236 since menu bar items are typically styled very differently from regular buttons
237 (flat, no borders or drop shadows, etc.).
238
239 \snippet ControlsSnippets.qml menuBarItem
240*/
241
242/*
243 \qmlproperty ControlStyle AbstractStylableControls::menuSeparator
244
245 Grouped property for styling \l [QtQuickControls]{MenuSeparator}.
246
247 Unset properties fall back to \l control.
248
249 \snippet ControlsSnippets.qml menuSeparator
250*/
251
252/*!
253 \qmlproperty ControlStyle AbstractStylableControls::page
254
255 Grouped property for styling \l [QtQuickControls]{Page}.
256
257 Unset properties fall back to \l pane.
258
259 Note that the \l [QtQuickControls]{Page::header}{header} and
260 \l [QtQuickControls]{Page::footer}{footer} of a \l [QtQuickControls]{Page} are
261 typically set by the application to a \l [QtQuickControls]{ToolBar} or
262 \l [QtQuickControls]{TabBar}, and those controls are styled separately.
263 To give a \l [QtQuickControls]{ToolBar} alternative styling when used inside
264 a \l [QtQuickControls]{Page}, use a \l StyleVariation:
265
266 \snippet ControlsSnippets.qml page
267*/
268
269/*!
270 \qmlproperty ControlStyle AbstractStylableControls::pane
271
272 Grouped property for styling \l [QtQuickControls]{Pane}.
273
274 Unset properties fall back to \l control.
275
276 \snippet ControlsSnippets.qml pane
277*/
278
279/*!
280 \qmlproperty ControlStyle AbstractStylableControls::popup
281
282 Grouped property for styling \l [QtQuickControls]{Popup}.
283
284 Unset properties fall back to \l control.
285
286 \snippet ControlsSnippets.qml popup
287*/
288
289/*!
290 \qmlproperty ControlStyle AbstractStylableControls::progressBar
291
292 Grouped property for styling \l [QtQuickControls]{ProgressBar}.
293 For a progress bar, the groove is styled through the indicator, while the progress
294 track is styled through the indicator's foreground.
295
296 Unset properties fall back to \l control.
297
298 \snippet ControlsSnippets.qml progressBar
299
300 StyleKit doesn't provide a dedicated property to style the indeterminate animation
301 of a progress bar. To change the animation, you need to implement a custom indicator
302 foreground \l {DelegateStyle::}{delegate} instead:
303
304 \snippet ControlsSnippets.qml progressBar indeterminate
305*/
306
307/*!
308 \qmlproperty ControlStyle AbstractStylableControls::radioButton
309
310 Grouped property for styling \l [QtQuickControls]{RadioButton}.
311
312 Unset properties fall back to \l abstractButton.
313
314 \snippet ControlsSnippets.qml radioButton
315*/
316
317/*!
318 \qmlproperty ControlStyle AbstractStylableControls::radioDelegate
319
320 Grouped property for styling \l [QtQuickControls]{RadioDelegate}.
321
322 Unset properties fall back to \l itemDelegate.
323
324 \snippet ControlsSnippets.qml radioDelegate
325*/
326
327/*!
328 \qmlproperty ControlStyle AbstractStylableControls::roundButton
329
330 Grouped property for styling \l [QtQuickControls]{RoundButton}.
331
332 Unset properties fall back to \l abstractButton.
333
334 \snippet ControlsSnippets.qml roundButton
335*/
336
337/*!
338 \qmlproperty ControlStyle AbstractStylableControls::scrollBar
339
340 Grouped property for styling \l [QtQuickControls]{ScrollBar}.
341 The groove is styled through \l {ControlStyleProperties::}{background}, and the
342 handle through \l {ControlStyleProperties::}{indicator}.
343
344 Unset properties fall back to \l control.
345
346 \snippet ControlsSnippets.qml scrollBar
347*/
348
349/*!
350 \qmlproperty ControlStyle AbstractStylableControls::scrollIndicator
351
352 Grouped property for styling \l [QtQuickControls]{ScrollIndicator}.
353 The groove is styled through \l {ControlStyleProperties::}{background}, and the
354 handle through \l {ControlStyleProperties::}{indicator}.
355
356 Unset properties fall back to \l control.
357
358 \snippet ControlsSnippets.qml scrollIndicator
359*/
360
361/*!
362 \qmlproperty ControlStyle AbstractStylableControls::scrollView
363
364 Grouped property for styling \l [QtQuickControls]{ScrollView}.
365
366 ScrollView itself has no visual delegates to style. Its scroll bars can be
367 styled separately through the \l scrollBar property. But you can use
368 \l {ControlStateStyle::padding}{padding} to control the space between
369 the scroll bars and the content area.
370
371 Unset properties fall back to \l control.
372
373 \snippet ControlsSnippets.qml scrollView
374*/
375
376/*
377 \qmlproperty ControlStyle AbstractStylableControls::searchField
378
379 Grouped property for styling \l [QtQuickControls]{SearchField}.
380
381 Unset properties fall back to \l control.
382
383 \snippet ControlsSnippets.qml searchfield
384*/
385
386/*!
387 \qmlproperty ControlStyle AbstractStylableControls::slider
388
389 Grouped property for styling \l [QtQuickControls]{Slider}.
390 For a slider, the groove is styled through the indicator, while the progress
391 track is styled through the indicator's foreground.
392
393 Unset properties fall back to \l control.
394
395 For vertical sliders, swap the \l {DelegateStyle::width}{width}
396 and \l {DelegateStyle::height}{height} of the relevant delegates
397 so that the control is taller than it is wide, as shown in the snippet below.
398
399 \snippet ControlsSnippets.qml slider
400*/
401
402/*!
403 \qmlproperty ControlStyle AbstractStylableControls::spinBox
404
405 Grouped property for styling \l [QtQuickControls]{SpinBox}.
406
407 Unset properties fall back to \l control.
408
409 \snippet ControlsSnippets.qml spinBox
410
411 \note It's currently only possible to position the up and down buttons to
412 be on the left or right side of the control, but not on top of each other.
413*/
414
415/*!
416 \qmlproperty ControlStyle AbstractStylableControls::swipeDelegate
417
418 Grouped property for styling \l [QtQuickControls]{SwipeDelegate}.
419
420 Unset properties fall back to \l itemDelegate.
421
422 \snippet ControlsSnippets.qml swipeDelegate
423*/
424
425/*!
426 \qmlproperty ControlStyle AbstractStylableControls::switchControl
427
428 Grouped property for styling \l [QtQuickControls]{Switch}.
429
430 Unset properties fall back to \l abstractButton.
431
432 \snippet ControlsSnippets.qml switchControl
433*/
434
435/*!
436 \qmlproperty ControlStyle AbstractStylableControls::switchDelegate
437
438 Grouped property for styling \l [QtQuickControls]{SwitchDelegate}.
439
440 Unset properties fall back to \l itemDelegate.
441
442 \snippet ControlsSnippets.qml switchDelegate
443*/
444
445/*!
446 \qmlproperty ControlStyle AbstractStylableControls::tabBar
447
448 Grouped property for styling \l [QtQuickControls]{TabBar}.
449
450 Unset properties fall back to \l pane.
451
452 \snippet ControlsSnippets.qml tabBar
453*/
454
455/*!
456 \qmlproperty ControlStyle AbstractStylableControls::tabButton
457
458 Grouped property for styling \l [QtQuickControls]{TabButton}.
459
460 Unset properties fall back to \l abstractButton.
461
462 \snippet ControlsSnippets.qml tabButton
463*/
464
465/*!
466 \qmlproperty ControlStyle AbstractStylableControls::textArea
467
468 Grouped property for styling \l [QtQuickControls]{TextArea}.
469
470 Unset properties fall back to \l textInput.
471
472 \snippet ControlsSnippets.qml textArea
473*/
474
475/*!
476 \qmlproperty ControlStyle AbstractStylableControls::textField
477
478 Grouped property for styling \l [QtQuickControls]{TextField}.
479
480 Unset properties fall back to \l textInput.
481
482 \snippet ControlsSnippets.qml textField
483*/
484
485/*!
486 \qmlproperty ControlStyle AbstractStylableControls::textInput
487
488 Grouped property for styling all text input controls, including
489 \l [QtQuickControls]{TextField} and \l [QtQuickControls]{TextArea}.
490
491 Unset properties fall back to \l control.
492
493 \snippet ControlsSnippets.qml textInput
494*/
495
496/*!
497 \qmlproperty ControlStyle AbstractStylableControls::toolBar
498
499 Grouped property for styling \l [QtQuickControls]{ToolBar}.
500
501 Unset properties fall back to \l pane.
502
503 \snippet ControlsSnippets.qml toolBar
504*/
505
506/*!
507 \qmlproperty ControlStyle AbstractStylableControls::toolButton
508
509 Grouped property for styling \l [QtQuickControls]{ToolButton}.
510
511 Unset properties fall back to \l abstractButton.
512
513 \snippet ControlsSnippets.qml toolButton
514*/
515
516/*!
517 \qmlproperty ControlStyle AbstractStylableControls::toolSeparator
518
519 Grouped property for styling \l [QtQuickControls]{ToolSeparator}.
520
521 Unset properties fall back to \l control.
522
523 For vertical separators, swap the \l {DelegateStyle::width}{width}
524 and \l {DelegateStyle::height}{height} of the relevant delegates
525 so that the control is taller than it is wide, as shown in the snippet below.
526
527 \snippet ControlsSnippets.qml toolSeparator
528*/
529
530using namespace Qt::StringLiterals;
531
532QQStyleKitControls::QQStyleKitControls(QObject *parent)
533 : QObject(parent)
534{
535}
536
538{
539 return QQmlListProperty<QObject>(this, &m_data);
540}
541
543{
544 return m_data;
545}
546
547/* Lazy-create the controls that the style is actually using, when accessed
548 * from the style/application (e.g from Style or Theme). We don't lazy
549 * create any controls while resolving style properties, as undefined controls would
550 * anyway not contain any property overrides. The properties have setters too, to
551 * allow the style/application to share custom ControlStyle the classical
552 * way, e.g button: ControlStyle { id: button }. */
553QQStyleKitControl* QQStyleKitControls::getControl(QQStyleKitExtendableControlType controlType) const
554{
555 return m_controls.value(controlType, nullptr);
556}
557
558#define IMPLEMENT_ACCESSORS(NAME, TYPE) QQStyleKitControl
559 *QQStyleKitControls::NAME() const \
560{
561 if (!m_controls.contains(TYPE)) {
562 auto *self = const_cast<QQStyleKitControls *>(this);
563 auto *control = new QQStyleKitControl(self);
564 self->m_controls.insert(TYPE, control);
565 }
566 return m_controls[TYPE]; \
567}void
568 QQStyleKitControls::set_ ## NAME(QQStyleKitControl *control) \
569{
570 m_controls.insert(TYPE, control); \
571}
572
573
574IMPLEMENT_ACCESSORS(abstractButton, QQStyleKitReader::ControlType::AbstractButton)
575IMPLEMENT_ACCESSORS(applicationWindow, QQStyleKitReader::ControlType::ApplicationWindow)
576IMPLEMENT_ACCESSORS(control, QQStyleKitReader::ControlType::Control)
577IMPLEMENT_ACCESSORS(button, QQStyleKitReader::ControlType::Button)
578IMPLEMENT_ACCESSORS(flatButton, QQStyleKitReader::ControlType::FlatButton)
579IMPLEMENT_ACCESSORS(checkBox, QQStyleKitReader::ControlType::CheckBox)
580IMPLEMENT_ACCESSORS(checkDelegate, QQStyleKitReader::ControlType::CheckDelegate)
581IMPLEMENT_ACCESSORS(comboBox, QQStyleKitReader::ControlType::ComboBox)
582IMPLEMENT_ACCESSORS(progressBar, QQStyleKitReader::ControlType::ProgressBar)
583IMPLEMENT_ACCESSORS(scrollBar, QQStyleKitReader::ControlType::ScrollBar)
584IMPLEMENT_ACCESSORS(scrollIndicator, QQStyleKitReader::ControlType::ScrollIndicator)
585IMPLEMENT_ACCESSORS(scrollView, QQStyleKitReader::ControlType::ScrollView)
586IMPLEMENT_ACCESSORS(searchField, QQStyleKitReader::SearchField)
587IMPLEMENT_ACCESSORS(slider, QQStyleKitReader::ControlType::Slider)
588IMPLEMENT_ACCESSORS(spinBox, QQStyleKitReader::ControlType::SpinBox)
589IMPLEMENT_ACCESSORS(swipeDelegate, QQStyleKitReader::ControlType::SwipeDelegate)
590IMPLEMENT_ACCESSORS(switchControl, QQStyleKitReader::ControlType::SwitchControl)
591IMPLEMENT_ACCESSORS(switchDelegate, QQStyleKitReader::ControlType::SwitchDelegate)
592IMPLEMENT_ACCESSORS(tabBar, QQStyleKitReader::ControlType::TabBar)
593IMPLEMENT_ACCESSORS(tabButton, QQStyleKitReader::ControlType::TabButton)
594IMPLEMENT_ACCESSORS(textField, QQStyleKitReader::ControlType::TextField)
595IMPLEMENT_ACCESSORS(textInput, QQStyleKitReader::ControlType::TextInput)
596IMPLEMENT_ACCESSORS(toolBar, QQStyleKitReader::ControlType::ToolBar)
597IMPLEMENT_ACCESSORS(toolButton, QQStyleKitReader::ControlType::ToolButton)
598IMPLEMENT_ACCESSORS(toolSeparator, QQStyleKitReader::ControlType::ToolSeparator)
599IMPLEMENT_ACCESSORS(radioButton, QQStyleKitReader::ControlType::RadioButton)
600IMPLEMENT_ACCESSORS(radioDelegate, QQStyleKitReader::ControlType::RadioDelegate)
601IMPLEMENT_ACCESSORS(roundButton, QQStyleKitReader::ControlType::RoundButton)
602IMPLEMENT_ACCESSORS(itemDelegate, QQStyleKitReader::ControlType::ItemDelegate)
603IMPLEMENT_ACCESSORS(popup, QQStyleKitReader::ControlType::Popup)
604IMPLEMENT_ACCESSORS(pane, QQStyleKitReader::ControlType::Pane)
605IMPLEMENT_ACCESSORS(page, QQStyleKitReader::ControlType::Page)
606IMPLEMENT_ACCESSORS(frame, QQStyleKitReader::ControlType::Frame)
607IMPLEMENT_ACCESSORS(label, QQStyleKitReader::ControlType::Label)
608IMPLEMENT_ACCESSORS(groupBox, QQStyleKitReader::ControlType::GroupBox)
609IMPLEMENT_ACCESSORS(textArea, QQStyleKitReader::ControlType::TextArea)
610IMPLEMENT_ACCESSORS(menu, QQStyleKitReader::ControlType::Menu)
611IMPLEMENT_ACCESSORS(menuBar, QQStyleKitReader::ControlType::MenuBar)
612IMPLEMENT_ACCESSORS(menuBarItem, QQStyleKitReader::ControlType::MenuBarItem)
613IMPLEMENT_ACCESSORS(menuItem, QQStyleKitReader::ControlType::MenuItem)
614IMPLEMENT_ACCESSORS(menuSeparator, QQStyleKitReader::ControlType::MenuSeparator)
615
616#undef IMPLEMENT_ACCESSORS
617
619{
620 for (auto *obj : children()) {
621 if (auto *customControl = qobject_cast<QQStyleKitCustomControl *>(obj)) {
622 const QQStyleKitExtendableControlType type = customControl->controlType();
623 const QQStyleKitExtendableControlType reserved
624 = QQStyleKitExtendableControlType(QQStyleKitReader::ControlType::Unspecified);
625 if (type >= reserved)
626 qmlWarning(this) << "CustomControls must use a controlType less than " << reserved;
627 if (m_controls.contains(type))
628 qmlWarning(this) << "CustomControl registered more than once: " << type;
629 m_controls.insert(type, customControl);
630 }
631 }
632}
633
634QT_END_NAMESPACE
635
636#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)