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
qqstylekit.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
4#include "qqstylekit_p.h"
8
9#include <QtGui/QStyleHints>
10
12
13QPointer<QQStyleKitAttached> QQStyleKitAttached::s_instance;
14bool QQStyleKitAttached::s_transitionsEnabled = true;
15
16/*!
17 \qmltype StyleKit
18 \nativetype QQStyleKit
19 \inqmlmodule Qt.labs.StyleKit
20 \brief A singleton for setting and accessing the current style.
21
22 \c StyleKit is a singleton for setting the application \l Style.
23
24 \snippet PlainStyleMain.qml 1
25
26 It also provides properties for global StyleKit configuration and debugging.
27
28 \labs
29
30 \sa Style, StyleVariation
31*/
32
33/*!
34 \qmlproperty Style StyleKit::style
35
36 The active style for the application.
37
38 Set this to a \l Style instance to apply it to all \l {Qt Quick Controls}.
39
40 \snippet PlainStyleMain.qml 1
41
42 \note For best startup performance, set the style on the root \l ApplicationWindow, before
43 any child controls.
44
45 \sa styleUrl, Style
46*/
47
48/*!
49 \qmlproperty url StyleKit::styleUrl
50
51 An alternative to \l style that loads a \l Style from a URL.
52
53 \sa style
54*/
55
56/*!
57 \qmlproperty bool StyleKit::transitionsEnabled
58
59 Controls whether transitions are enabled globally.
60
61 Set this to \c false to disable all transitions in the
62 current style.
63
64 The default value is \c true.
65
66 \sa {ControlStyle::transition}
67*/
68
69/*!
70 \qmlproperty StyleKitDebug StyleKit::debug
71 \readonly
72
73 A run-time debugging tool that can be used to trace
74 style properties for a specific \l Control.
75*/
76
77/*!
78 \qmlmethod bool StyleKit::styleLoaded()
79
80 Returns \c true when the active \l style and its current \l {Style::}{theme} have both
81 finished loading. This can be used to defer initialization logic that
82 depends on resolved style properties.
83
84 \sa style, {Style::}{theme}
85*/
86
87QQStyleKit::QQStyleKit(QObject *parent)
88 : QObject(parent)
89{
90}
91
92QQStyleKitAttached *QQStyleKit::qmlAttachedProperties(QObject *obj)
93{
94 /* QQStyleKitAttached is a singleton. It doesn't matter where it's
95 * used from in the application, it will always represent the same
96 * application global style and theme. */
97 if (!QQStyleKitAttached::s_instance)
98 QQStyleKitAttached::s_instance = new QQStyleKitAttached(QGuiApplication::instance());
99 if (!QQStyleKitAttached::s_instance->m_engine && obj)
100 QQStyleKitAttached::s_instance->m_engine = qmlEngine(obj);
101 return QQStyleKitAttached::s_instance.get();
102}
103
104QQStyleKitAttached::QQStyleKitAttached(QObject *parent)
105 : QObject(parent)
106{
107 connect(QGuiApplication::styleHints(), &QStyleHints::colorSchemeChanged, this, [this](){
108 if (m_style && QString::compare(m_style->themeName(), "System"_L1, Qt::CaseInsensitive) == 0)
109 m_style->recreateTheme();
110 });
111}
112
114{
115 QQStyleKitAttached::s_instance = nullptr;
116 if (m_ownsStyle) {
117 delete m_style;
118 m_style = nullptr;
119 }
120}
121
122QQStyleKitStyle *QQStyleKitAttached::style() const
123{
124 return m_style;
125}
126
127void QQStyleKitAttached::setStyle(QQStyleKitStyle *style)
128{
129 if (m_style == style)
130 return;
131
132 if (m_ownsStyle)
133 m_style->deleteLater();
134
135 m_style = style;
136 m_style->reapplyStyle();
137
138 emit styleChanged();
139}
140
142{
143 return m_styleUrl;
144}
145
146void QQStyleKitAttached::setStyleUrl(const QUrl &styleUrl)
147{
148 if (m_styleUrl == styleUrl)
149 return;
150
151 m_styleUrl = styleUrl;
152
153 Q_ASSERT(m_engine);
154 QQmlComponent component(m_engine, styleUrl, this);
155 if (!component.errors().isEmpty()) {
156 qmlWarning(this) << "Could not create a Style from url '" << styleUrl << "': " << component.errorString();
157 return;
158 }
159
160 /* Avoid creating anything other than StyleKit Style objects by checking the metaobject
161 * of the root type before creating the object. This to avoid instantiating items or other
162 * object that could cause unwanted side effects. */
163 QQmlComponentPrivate *componentPrivate = QQmlComponentPrivate::get(&component);
164 const auto compilationUnit = componentPrivate->compilationUnit();
165 const auto propertyCache = compilationUnit ? compilationUnit->rootPropertyCache() : nullptr;
166 const auto firstMetaObject = propertyCache ? propertyCache->firstCppMetaObject() : nullptr;
167 if (!firstMetaObject || !firstMetaObject->inherits(&QQStyleKitStyle::staticMetaObject)) {
168 qmlWarning(this) << "Could not create a Style from url '" << styleUrl << "': the root item is not a Style.";
169 return;
170 }
171
172 auto *style = qobject_cast<QQStyleKitStyle *>(component.create());
173 if (!style) {
174 qmlWarning(this) << "Could not create a Style from url '" << styleUrl << "': failed to create an instance of the resolved Component.";
175 return;
176 }
177
178 style->componentComplete();
179 setStyle(style);
180 m_ownsStyle = true;
181 emit styleUrlChanged();
182}
183
185{
186 return s_transitionsEnabled;
187}
188
190{
191 if (enabled == s_transitionsEnabled)
192 return;
193
194 s_transitionsEnabled = enabled;
195 emit transitionsEnabledChanged();
196}
197
199{
200 return &const_cast<QQStyleKitAttached *>(this)->m_debug;
201}
202
204{
205 return m_style && m_style->loaded();
206}
207
208QT_END_NAMESPACE
209
210#include "moc_qqstylekit_p.cpp"
Q_INVOKABLE bool styleLoaded() const
QQStyleKitStyle * style() const
QUrl styleUrl() const
void setStyle(QQStyleKitStyle *style)
void setTransitionsEnabled(bool enabled)
QQStyleKitDebug * debug() const
bool transitionsEnabled() const
void setStyleUrl(const QUrl &styleUrl)
Combined button and popup list for selecting options.