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
qqstylekitcontrol.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 ControlStyle
12 \inqmlmodule Qt.labs.StyleKit
13 \inherits ControlStateStyle
14 \brief Defines the style for a control in the \c normal state
15
16 A ControlStyle describes how a \l Control should be styled. Its API
17 largely mirrors that of a Qt Quick Control: it provides grouped
18 properties for delegates such as
19 \l {ControlState::background}{background},
20 \l {ControlState::indicator}{indicator},
21 \l {ControlState::handle}{handle}, and
22 \l {ControlState::text}{text}, along with layout
23 properties such as
24 \l {ControlState::padding}{padding} and
25 \l {ControlState::spacing}{spacing}.
26 If you are familiar with the API of a \l Control in Qt Quick Controls,
27 you should find the ControlStyle API easy to follow.
28
29 ControlStyle inherits \l ControlStateStyle because it represents the
30 \e normal state: properties set directly on a ControlStyle describe
31 how the control looks when no other state is active. State-specific
32 overrides are set through nested states, such as \l {ControlStateStyle::}{hovered}
33 \l {ControlStateStyle::}{pressed}, and \l {ControlStateStyle::}{checked}.
34
35 \l {AbstractStylableControls}{Each stylable control} in a \l Style, \l Theme, or \l StyleVariation is a ControlStyle.
36 For example, in the snippet below, \l {AbstractStylableControls::}{control},
37 \l {AbstractStylableControls::}{button} and \l {AbstractStylableControls::}{radioButton}
38 are all ControlStyles:
39
40 \snippet ControlStyleSnippets.qml ControlStyle
41
42 \sa {AbstractStylableControls}{All stylable controls}, Style, Theme,
43 StyleVariation, ControlStateStyle, DelegateStyle
44*/
45
46/*!
47 \qmlproperty list<StyleVariation> ControlStyle::variations
48
49 A list of \l {StyleVariation}{type variations} for this control type.
50
51 A type variation provides alternate styling for controls that are
52 children (or descendants) of this control type. For example, you
53 can use it to style all \l {Button}{buttons} inside a \l {Frame}{frame}
54 differently from buttons elsewhere:
55
56 \snippet VariationSnippets.qml frame with variation
57
58 You can also set it back to an empty list for a subtype, if you don't
59 want it to inherit the variations set on a base type:
60
61 \snippet VariationSnippets.qml groupbox without variation
62
63 Unlike instance variations — which are applied to specific control
64 instances from the application via the
65 \l {StyleVariation.variations} attached property — type
66 variations are applied to \e{all} instances of a control type from
67 the \l Style, without requiring the application to opt in.
68
69 \sa StyleVariation
70*/
71
76
77QQmlListProperty<QQStyleKitVariation> QQStyleKitControl::variations()
78{
79 const bool isWrite = subclass() == QQSK::Subclass::QQStyleKitState;
80 if (isWrite) {
81 if (!QQStyleKitPropertyResolver::hasLocalStyleProperty(this, QQSK::Property::Variations)) {
82 /* We need to handle both the setter and the getter in the getter, since QML doesn't
83 * use a separate setter for QQmlListProperty. This means that we need to initialize
84 * the storage with an empty QList, since we need to be prepared for the QML engine
85 * inserting elements into it behind our back. A negative side-effect of this logic
86 * is that a simple read of the property for a QQStyleKitState will also accidentally
87 * populate the local storage of that QQStylKitState, and thereby affect propagation.
88 * Note: since Variations is not a part of QQStyleKitProperties, it's not possible,
89 * and there is also no point, in emitting a changed signal globally, since a
90 * QQuickStyleKitReader inherits QQStyleKitProperties and not QQStyleKitControl,
91 * and as such, doesn't have a 'variations' property. */
92 auto *newList = new QList<QQStyleKitVariation *>();
93 setStyleProperty(QQSK::Property::Variations, newList);
94 }
95 }
96
97 /* Read the property, taking propagation into account. Note that since QQmlListProperty takes
98 * a pointer to a QList as argument, we need to store the list as a pointer as well */
99 const QVariant variant = QQStyleKitPropertyResolver::readStyleProperty(this, QQSK::Property::Variations);
100 if (!variant.isValid()) {
101 // Return a read-only list. Trying to change this list from the app has no effect.
102 static auto *emptyList = new QList<QQStyleKitVariation *>();
103 return QQmlListProperty<QQStyleKitVariation>(this, emptyList);
104 }
105
106 const auto value = qvariant_cast<QList<QQStyleKitVariation *> *>(variant);
107 return QQmlListProperty<QQStyleKitVariation>(this, value);
108}
109
110QVariant QQStyleKitControl::readStyleProperty(PropertyStorageId key) const
111{
112 return m_storage.value(key);
113}
114
115void QQStyleKitControl::writeStyleProperty(PropertyStorageId key, const QVariant &value)
116{
117 m_storage.insert(key, value);
118}
119
120QQStyleKitControls *QQStyleKitControl::controls() const
121{
122 Q_ASSERT(qobject_cast<QQStyleKitControls *>(parent()));
123 return static_cast<QQStyleKitControls *>(parent());
124}
125
126QQStyleKitExtendableControlType QQStyleKitControl::controlType() const
127{
128 const auto &controlsMap = controls()->m_controls;
129 Q_ASSERT(std::find(controlsMap.begin(), controlsMap.end(), this) != controlsMap.end());
130 return controlsMap.key(const_cast<QQStyleKitControl *>(this));
131}
132
133QT_END_NAMESPACE
134
135#include "moc_qqstylekitcontrol_p.cpp"
QObject * parent
Definition qobject.h:74
\inmodule QtCore
Definition qobject.h:106
Combined button and popup list for selecting options.