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