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