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
qt6-changes.qdoc
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
3
4/*!
5 \page qml-changes-qt6.html
6 \title Changes to Qt QML
7 \ingroup changes-qt-5-to-6
8 \brief Migrate Qt QML to Qt 6.
9
10 Qt 6 is a result of the conscious effort to make the framework more
11 efficient and easy to use.
12
13 We try to maintain binary and source compatibility for all the public
14 APIs in each release. But some changes were inevitable in an effort to
15 make Qt a better framework.
16
17 In this topic we summarize those changes in Qt QML, and provide
18 guidance to handle them.
19
20 \section1 QML language
21
22 \section2 URL resolution
23
24 In Qt 5, relative urls were often, albeit inconsistently, directly resolved, especially when
25 assigned to an url property. In Qt 6 this is no longer the case.
26
27 If you had a QML file stored under "/home/qml/example.qml", and "example.qml" contained
28 \code
29 property url imageFolder: "./images"
30 \endcode
31 then the url property would store the URL "/home/qml/images". This made it impossible to use
32 relative URLs in QML in this way, so in Qt 6, the URL stays relative, and only gets resolved
33 when this is required (e.g. when it is used as the source of an Image component).
34 If you depend on the old behavior, you can use \c Qt.resolvedUrl
35
36 For example, if you have code like
37
38 \code
39 property url imageFolder: "./images"
40 \endcode
41
42 you can rewrite it as
43
44 \code
45 property url imageFolder: Qt.resolvedUrl("./images")
46 \endcode
47
48 Qt.resolvedUrl can be used in both Qt 5 and 6.
49
50 As a porting aid, the \c{QML_COMPAT_RESOLVE_URLS_ON_ASSIGNMENT} environment variable can be set
51 to 1 to obtain the Qt 5 behavior. This is possible since Qt 6.2.2. However, it is recommended
52 to only use this to unblock a port, and to use \c Qt.resolvedUrl as explained above.
53
54 \section2 Variant Properties
55
56 \c variant properties, which have been marked as obsolete since Qt 5, are now treated in exactly
57 the same way as \c var properties.
58 Code that relied on implicit string conversion triggered on assignment to variant properties
59 should be updated to explicitly create an object of the correct type.
60
61 For example, if you have code like
62
63 \code
64 property variant myColor: "red"
65 \endcode
66
67 you can rewrite it as
68
69 \code
70 property variant myColor: Qt.color("red")
71 \endcode
72
73 Implicit conversions were done for strings that could be parsed as
74 \list
75 \li color (use Qt.color instead),
76 \li date (use the Date object instead),
77 \li rect (use Qt.rect instead) and
78 \li size (use Qt.size instead)
79 \endlist
80
81 \c variant still remains a deprecated keyword in Qt 6, though new code is strongly encouraged to
82 use \c var properties instead.
83
84 \note If the type of the property is known not to change, use a property of the concrete type,
85 instead of a \c var property.
86
87 \note These conversions were also applied to \c QVariant properties of classes registered with
88 the engine. As with \c variant properties, code that relied on implicit string conversions need
89 to use the corresponding functions of the Qt object.
90
91 \section1 Source Incompatible API Changes
92
93 \section2 Changed API
94
95 \c QQmlListProperty's \c CountFunction and \c AtFunction have been changed to use \c qsizetype
96 instead of \c int to align with the corresponding changes in Qt's containers.
97
98 For example, if you have code like
99
100 \code
101 int myCountFunction(QQmlListProperty<MyType> *);
102 MyType *myAtFunction(QQmlListProperty<MyType> *, int);
103
104 QQmlListProperty<MyType> myReadOnlyList(containingObject, container, &myCountFunction,
105 &myAtFunction);
106 \endcode
107
108 you can rewrite it as
109
110 \code
111 qsizetype myCountFunction(QQmlListProperty<MyType> *);
112 MyType *myAtFunction(QQmlListProperty<MyType> *, qsizetype);
113
114 QQmlListProperty<MyType> myReadOnlyList(containingObject, container, &myCountFunction,
115 &myAtFunction);
116 \endcode
117
118 Code which needs to supports both Qt 5 and Qt 6 can either use a typedef which is \c int in Qt 5
119 and \c qsizetype in Qt 6, or use \c QList::size_type, which already is such a type alias.
120
121 \section2 Removed API
122
123 Various deprecated functions have been removed.
124
125 \list
126 \li The QQmlListProperty constructor taking a reference has been removed.
127
128 For example, if you have code like
129
130 \code
131 QQmlListProperty<QObject>(owner, owner->objectList);
132 \endcode
133
134 you can rewrite it as
135
136 \code
137 QQmlListProperty<QObject>(owner, &owner->objectList);
138 \endcode
139
140 \li The functions \c qmlDebug, \c qmlInfo, \c qmlWarning, \c qmlContext and \c qmlEngine used
141 to exist both in the global namespace (or Qt namespace in namespaced builds), and in the \c
142 QtQml namespace. These functions now exist only in the global namespace.
143
144 For example, if you have code like
145
146 \code
147 QQmlEngine *engine = QtQml::qmlEngine(qmlObject);
148 \endcode
149
150 you can rewrite it as
151
152 \code
153 QQmlEngine *engine = qmlEngine(qmlObject);
154 \endcode
155
156 \li The \c qmlRegisterType overload taking no arguments has been removed. Use
157 \c qmlRegisterAnonymousType instead, or switch to declarative type registration with
158 \c QML_ANONYMOUS.
159
160 For example, if you have code like
161
162 \code
163 class AnonymousType : public QObject {
164 // ...
165 };
166
167 qmlRegisterType<AnonymousType>();
168 \endcode
169
170 you can rewrite it as
171
172 \code
173 class AnonymousType : public QObject {
174 // ...
175 };
176
177 qmlRegisterAnonymousType<AnonymousType>("MyModule", 1);
178 \endcode
179
180 Or alternatively
181 \code
182 class AnonymousType : public QObject {
183 QML_ANONYMOUS
184 // ...
185 };
186 \endcode
187
188 \li The overloads of \c qmlRegisterExtendedType and \c qmlRegisterInterface
189 which take no version argument have been removed. Use the overloads providing a
190 version, or switch to declarative type registration with QML_EXTENDED
191 and QML_INTERFACE.
192
193 For example, if you have code like
194
195 \code
196 struct GreetInterface
197 {
198 virtual ~GreetInterface();
199 virtual void greet();
200 };
201 Q_DECLARE_INTERFACE(GreetInterface, "org.hi.GreetInterface")
202
203 qmlRegisterInterface<GreetInterface>("Greeter");
204 \endcode
205
206 you can rewrite it as
207
208 \code
209 struct GreetInterface
210 {
211 virtual ~GreetInterface();
212 virtual void greet();
213 };
214 Q_DECLARE_INTERFACE(GreetInterface, "org.hi.GreetInterface")
215
216 qmlRegisterInterface<GreetInterface>("Greeter", 1);
217 \endcode
218
219 Alternatively
220
221 \code
222 struct GreetInterface
223 {
224 QML_INTERFACE(Greeter)
225 virtual ~GreetInterface();
226 virtual void greet();
227 };
228 Q_DECLARE_INTERFACE(GreetInterface, "org.hi.GreetInterface")
229 \endcode
230
231 \note In new code, declarative type registration should be preferred.
232
233 \li The function \c QJSValue::engine has been removed. If access to the engine is required, a
234 reference to it must be stored instead.
235
236 \li \c qmlAttachedPropertiesObjectById and \c qmlAttachedPropertiesObject(int *, const QObject *,
237 const QMetaObject *, bool) have been removed. Use the
238 \c qmlAttachedPropertiesObject(QObject *, QQmlAttachedPropertiesFunc, bool) overload of
239 \c qmlAttachedPropertiesObject instead.
240
241 \li \c QJSEngine::installTranslatorFunctions has been removed. \c QJSEngine::installExtensions
242 is available as a replacement.
243
244 For example, if you have code like
245
246 \code
247 QJSEngine engine;
248 engine.installTranslatorFunctions();
249 \endcode
250
251 you can rewrite it as
252
253 \code
254 QJSEngine engine;
255 engine.installExtensions(QJSEngine::TranslationExtension);
256 \endcode
257
258 \endlist
259
260 \sa {Modern QML modules}, {Port QML modules to CMake}
261*/