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}, and \l [QtQuickControls]{Switch}.
63 Unset properties fall back to \l control.
64
65 \snippet ControlsSnippets.qml abstractButton
66
67 \sa {Qt Labs StyleKit}{Control Types}
68*/
69
70/*!
71 \qmlproperty ControlStyle AbstractStylableControls::applicationWindow
72
73 Grouped property for styling \l [QtQuickControls] ApplicationWindow.
74
75 Unset properties fall back to \l control.
76
77 Use \c applicationWindow to set the background color of the window:
78
79 \snippet ControlsSnippets.qml applicationWindow
80
81 \note The application needs to use ApplicationWindow, not Window, for this to take effect.
82*/
83
84/*!
85 \qmlproperty ControlStyle AbstractStylableControls::button
86
87 Grouped property for styling \l [QtQuickControls]{Button}.
88
89 Unset properties fall back to \l abstractButton.
90
91 \snippet ControlsSnippets.qml button
92*/
93
94/*!
95 \qmlproperty ControlStyle AbstractStylableControls::checkBox
96
97 Grouped property for styling \l [QtQuickControls]{CheckBox}.
98
99 Unset properties fall back to \l abstractButton.
100
101 \snippet ControlsSnippets.qml checkBox
102*/
103
104/*!
105 \qmlproperty ControlStyle AbstractStylableControls::comboBox
106
107 Grouped property for styling \l [QtQuickControls]{ComboBox}.
108
109 Unset properties fall back to \l control.
110
111 \snippet ControlsSnippets.qml comboBox
112*/
113
114/*!
115 \qmlproperty ControlStyle AbstractStylableControls::flatButton
116
117 Grouped property for styling flat buttons (buttons with no visible
118 background in their normal state). The styling will take effect for
119 a \l [QtQuickControls]{Button} if \l [QtQuickControls]{Button::flat}{Button.flat} is set to \c true.
120
121 Unset properties fall back to \l abstractButton.
122
123 \snippet ControlsSnippets.qml flatButton
124*/
125
126/*!
127 \qmlproperty ControlStyle AbstractStylableControls::frame
128
129 Grouped property for styling \l [QtQuickControls]{Frame}.
130
131 Unset properties fall back to \l pane.
132
133 \snippet ControlsSnippets.qml frame
134*/
135
136/*!
137 \qmlproperty ControlStyle AbstractStylableControls::groupBox
138
139 Grouped property for styling \l [QtQuickControls]{GroupBox}.
140
141 Unset properties fall back to \l frame.
142
143 \snippet ControlsSnippets.qml groupBox
144*/
145
146/*!
147 \qmlproperty ControlStyle AbstractStylableControls::itemDelegate
148
149 Grouped property for styling \l [QtQuickControls]{ItemDelegate}.
150
151 Unset properties fall back to \l control.
152
153 \note In Qt Quick Controls, \l [QtQuickControls]{ItemDelegate} inherits from
154 \l [QtQuickControls]{AbstractButton}. In StyleKit, however, \c itemDelegate
155 falls back to \l control rather than \l abstractButton, since delegates are
156 typically \e styled very differently from buttons (flat, no borders or drop shadows, etc.).
157
158 \snippet ControlsSnippets.qml itemDelegate
159*/
160
161/*!
162 \qmlproperty ControlStyle AbstractStylableControls::label
163
164 Grouped property for styling \l [QtQuickControls]{Label}.
165
166 Unset properties fall back to \l control.
167
168 \snippet ControlsSnippets.qml label
169*/
170
171/*!
172 \qmlproperty ControlStyle AbstractStylableControls::page
173
174 Grouped property for styling \l [QtQuickControls]{Page}.
175
176 Unset properties fall back to \l pane.
177
178 Note that the \l [QtQuickControls]{Page::header}{header} and
179 \l [QtQuickControls]{Page::footer}{footer} of a \l [QtQuickControls]{Page} are
180 typically set by the application to a \l [QtQuickControls]{ToolBar} or
181 \l [QtQuickControls]{TabBar}, and those controls are styled separately.
182 To give a \l [QtQuickControls]{ToolBar} alternative styling when used inside
183 a \l [QtQuickControls]{Page}, use a \l StyleVariation:
184
185 \snippet ControlsSnippets.qml page
186*/
187
188/*!
189 \qmlproperty ControlStyle AbstractStylableControls::pane
190
191 Grouped property for styling \l [QtQuickControls]{Pane}.
192
193 Unset properties fall back to \l control.
194
195 \snippet ControlsSnippets.qml pane
196*/
197
198/*!
199 \qmlproperty ControlStyle AbstractStylableControls::popup
200
201 Grouped property for styling \l [QtQuickControls]{Popup}.
202
203 Unset properties fall back to \l control.
204
205 \snippet ControlsSnippets.qml popup
206*/
207
208/*!
209 \qmlproperty ControlStyle AbstractStylableControls::progressBar
210
211 Grouped property for styling \l [QtQuickControls]{ProgressBar}.
212 For a progress bar, the groove is styled through the indicator, while the progress
213 track is styled through the indicator's foreground.
214
215 Unset properties fall back to \l control.
216
217 \snippet ControlsSnippets.qml progressBar
218
219 StyleKit doesn't provide a dedicated property to style the indeterminate animation
220 of a progress bar. To change the animation, you need to implement a custom indicator
221 foreground \l {DelegateStyle::}{delegate} instead:
222
223 \snippet ControlsSnippets.qml progressBar indeterminate
224*/
225
226/*!
227 \qmlproperty ControlStyle AbstractStylableControls::radioButton
228
229 Grouped property for styling \l [QtQuickControls]{RadioButton}.
230
231 Unset properties fall back to \l abstractButton.
232
233 \snippet ControlsSnippets.qml radioButton
234*/
235
236/*!
237 \qmlproperty ControlStyle AbstractStylableControls::scrollBar
238
239 Grouped property for styling \l [QtQuickControls]{ScrollBar}.
240 The groove is styled through \l {ControlStyleProperties::}{background}, and the
241 handle through \l {ControlStyleProperties::}{indicator}.
242
243 Unset properties fall back to \l control.
244
245 \snippet ControlsSnippets.qml scrollBar
246*/
247
248/*!
249 \qmlproperty ControlStyle AbstractStylableControls::scrollIndicator
250
251 Grouped property for styling \l [QtQuickControls]{ScrollIndicator}.
252 The groove is styled through \l {ControlStyleProperties::}{background}, and the
253 handle through \l {ControlStyleProperties::}{indicator}.
254
255 Unset properties fall back to \l control.
256
257 \snippet ControlsSnippets.qml scrollIndicator
258*/
259
260/*!
261 \qmlproperty ControlStyle AbstractStylableControls::scrollView
262
263 Grouped property for styling \l [QtQuickControls]{ScrollView}.
264
265 ScrollView itself has no visual delegates to style. Its scroll bars can be
266 styled separately through the \l scrollBar property. But you can use
267 \l {ControlStateStyle::padding}{padding} to control the space between
268 the scroll bars and the content area.
269
270 Unset properties fall back to \l control.
271
272 \snippet ControlsSnippets.qml scrollView
273*/
274
275/*!
276 \qmlproperty ControlStyle AbstractStylableControls::slider
277
278 Grouped property for styling \l [QtQuickControls]{Slider}.
279 For a slider bar, the groove is styled through the indicator, while the progress
280 track is styled through the indicator's foreground.
281 Unset properties fall back to \l control.
282
283 \snippet ControlsSnippets.qml slider
284*/
285
286/*!
287 \qmlproperty ControlStyle AbstractStylableControls::spinBox
288
289 Grouped property for styling \l [QtQuickControls]{SpinBox}.
290
291 Unset properties fall back to \l control.
292
293 \snippet ControlsSnippets.qml spinBox
294
295 \note It's currently only possible to position the up and down buttons to
296 be on the left or right side of the control, but not on top of each other.
297*/
298
299/*!
300 \qmlproperty ControlStyle AbstractStylableControls::switchControl
301
302 Grouped property for styling \l [QtQuickControls]{Switch}.
303
304 Unset properties fall back to \l abstractButton.
305
306 \snippet ControlsSnippets.qml switchControl
307*/
308
309/*!
310 \qmlproperty ControlStyle AbstractStylableControls::tabBar
311
312 Grouped property for styling \l [QtQuickControls]{TabBar}.
313
314 Unset properties fall back to \l pane.
315
316 \snippet ControlsSnippets.qml tabBar
317*/
318
319/*!
320 \qmlproperty ControlStyle AbstractStylableControls::tabButton
321
322 Grouped property for styling \l [QtQuickControls]{TabButton}.
323
324 Unset properties fall back to \l abstractButton.
325
326 \snippet ControlsSnippets.qml tabButton
327*/
328
329/*!
330 \qmlproperty ControlStyle AbstractStylableControls::textArea
331
332 Grouped property for styling \l [QtQuickControls]{TextArea}.
333
334 Unset properties fall back to \l textInput.
335
336 \snippet ControlsSnippets.qml textArea
337*/
338
339/*!
340 \qmlproperty ControlStyle AbstractStylableControls::textField
341
342 Grouped property for styling \l [QtQuickControls]{TextField}.
343
344 Unset properties fall back to \l textInput.
345
346 \snippet ControlsSnippets.qml textField
347*/
348
349/*!
350 \qmlproperty ControlStyle AbstractStylableControls::textInput
351
352 Grouped property for styling all text input controls, including
353 \l [QtQuickControls]{TextField} and \l [QtQuickControls]{TextArea}.
354
355 Unset properties fall back to \l control.
356
357 \snippet ControlsSnippets.qml textInput
358*/
359
360/*!
361 \qmlproperty ControlStyle AbstractStylableControls::toolBar
362
363 Grouped property for styling \l [QtQuickControls]{ToolBar}.
364
365 Unset properties fall back to \l pane.
366
367 \snippet ControlsSnippets.qml toolBar
368*/
369
370/*!
371 \qmlproperty ControlStyle AbstractStylableControls::toolButton
372
373 Grouped property for styling \l [QtQuickControls]{ToolButton}.
374
375 Unset properties fall back to \l abstractButton.
376
377 \snippet ControlsSnippets.qml toolButton
378*/
379
380/*!
381 \qmlproperty ControlStyle AbstractStylableControls::toolSeparator
382
383 Grouped property for styling \l [QtQuickControls]{ToolSeparator}.
384
385 Unset properties fall back to \l control.
386
387 \snippet ControlsSnippets.qml toolSeparator
388*/
389
390using namespace Qt::StringLiterals;
391
392QQStyleKitControls::QQStyleKitControls(QObject *parent)
393 : QObject(parent)
394{
395}
396
398{
399 return QQmlListProperty<QObject>(this, &m_data);
400}
401
403{
404 return m_data;
405}
406
407/* Lazy-create the controls that the style is actually using, when accessed
408 * from the style/application (e.g from Style or Theme). We don't lazy
409 * create any controls while resolving style properties, as undefined controls would
410 * anyway not contain any property overrides. The properties have setters too, to
411 * allow the style/application to share custom ControlStyle the classical
412 * way, e.g button: ControlStyle { id: button }. */
413QQStyleKitControl* QQStyleKitControls::getControl(QQStyleKitExtendableControlType controlType) const
414{
415 return m_controls.value(controlType, nullptr);
416}
417
418#define IMPLEMENT_ACCESSORS(NAME, TYPE) QQStyleKitControl
419 *QQStyleKitControls::NAME() const \
420{
421 if (!m_controls.contains(TYPE)) {
422 auto *self = const_cast<QQStyleKitControls *>(this);
423 auto *control = new QQStyleKitControl(self);
424 self->m_controls.insert(TYPE, control);
425 }
426 return m_controls[TYPE]; \
427}void
428 QQStyleKitControls::set_ ## NAME(QQStyleKitControl *control) \
429{
430 m_controls.insert(TYPE, control); \
431}
432
433
434IMPLEMENT_ACCESSORS(abstractButton, QQStyleKitReader::ControlType::AbstractButton)
435IMPLEMENT_ACCESSORS(applicationWindow, QQStyleKitReader::ControlType::ApplicationWindow)
436IMPLEMENT_ACCESSORS(control, QQStyleKitReader::ControlType::Control)
437IMPLEMENT_ACCESSORS(button, QQStyleKitReader::ControlType::Button)
438IMPLEMENT_ACCESSORS(flatButton, QQStyleKitReader::ControlType::FlatButton)
439IMPLEMENT_ACCESSORS(checkBox, QQStyleKitReader::ControlType::CheckBox)
440IMPLEMENT_ACCESSORS(comboBox, QQStyleKitReader::ControlType::ComboBox)
441IMPLEMENT_ACCESSORS(progressBar, QQStyleKitReader::ControlType::ProgressBar)
442IMPLEMENT_ACCESSORS(scrollBar, QQStyleKitReader::ControlType::ScrollBar)
443IMPLEMENT_ACCESSORS(scrollIndicator, QQStyleKitReader::ControlType::ScrollIndicator)
444IMPLEMENT_ACCESSORS(scrollView, QQStyleKitReader::ControlType::ScrollView)
445IMPLEMENT_ACCESSORS(slider, QQStyleKitReader::ControlType::Slider)
446IMPLEMENT_ACCESSORS(spinBox, QQStyleKitReader::ControlType::SpinBox)
447IMPLEMENT_ACCESSORS(switchControl, QQStyleKitReader::ControlType::SwitchControl)
448IMPLEMENT_ACCESSORS(tabBar, QQStyleKitReader::ControlType::TabBar)
449IMPLEMENT_ACCESSORS(tabButton, QQStyleKitReader::ControlType::TabButton)
450IMPLEMENT_ACCESSORS(textField, QQStyleKitReader::ControlType::TextField)
451IMPLEMENT_ACCESSORS(textInput, QQStyleKitReader::ControlType::TextInput)
452IMPLEMENT_ACCESSORS(toolBar, QQStyleKitReader::ControlType::ToolBar)
453IMPLEMENT_ACCESSORS(toolButton, QQStyleKitReader::ControlType::ToolButton)
454IMPLEMENT_ACCESSORS(toolSeparator, QQStyleKitReader::ControlType::ToolSeparator)
455IMPLEMENT_ACCESSORS(radioButton, QQStyleKitReader::ControlType::RadioButton)
456IMPLEMENT_ACCESSORS(itemDelegate, QQStyleKitReader::ControlType::ItemDelegate)
457IMPLEMENT_ACCESSORS(popup, QQStyleKitReader::ControlType::Popup)
458IMPLEMENT_ACCESSORS(pane, QQStyleKitReader::ControlType::Pane)
459IMPLEMENT_ACCESSORS(page, QQStyleKitReader::ControlType::Page)
460IMPLEMENT_ACCESSORS(frame, QQStyleKitReader::ControlType::Frame)
461IMPLEMENT_ACCESSORS(label, QQStyleKitReader::ControlType::Label)
462IMPLEMENT_ACCESSORS(groupBox, QQStyleKitReader::ControlType::GroupBox)
463IMPLEMENT_ACCESSORS(textArea, QQStyleKitReader::ControlType::TextArea)
464
465#undef IMPLEMENT_ACCESSORS
466
468{
469 for (auto *obj : children()) {
470 if (auto *customControl = qobject_cast<QQStyleKitCustomControl *>(obj)) {
471 const QQStyleKitExtendableControlType type = customControl->controlType();
472 const QQStyleKitExtendableControlType reserved
473 = QQStyleKitExtendableControlType(QQStyleKitReader::ControlType::Unspecified);
474 if (type >= reserved)
475 qmlWarning(this) << "CustomControls must use a controlType less than " << reserved;
476 if (m_controls.contains(type))
477 qmlWarning(this) << "CustomControl registered more than once: " << type;
478 m_controls.insert(type, customControl);
479 }
480 }
481}
482
483QT_END_NAMESPACE
484
485#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)