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-port-to-qt-add-qml-module.qdoc
Go to the documentation of this file.
1
// Copyright (C) 2025 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
3
4
/*!
5
\page qt6-port-to-qt-add-qml-module.html
6
\title Port QML modules to CMake
7
\brief Port your QML modules to the qt_add_qml_module CMake API.
8
9
QML modules have become more powerful and easier to use in Qt 6. The following sections describe
10
how to port QML modules to the \l qt_add_qml_module CMake API.
11
12
See also \l{Modern QML modules} on how to modernize a QML module that already uses \l
13
qt_add_qml_module.
14
15
\section1 Identify issues to fix
16
17
Use \l qmllint to support you through the process.
18
19
Each QML module defined with \l qt_add_qml_module has a \c{_qmllint} CMake target that you can
20
use to identify potential issues or improvements. For a QML module called \c MyQmlLibrary use
21
\c{MyQmlLibrary_qmllint}, for example. To run \l qmllint on all QML modules, use \c
22
{all_qmllint}.
23
24
The warning categories of \l qmllint that hint at QML module issues are:
25
\list
26
\li \l{Warnings occurred while importing}{[import]}
27
\li \l{Unused imports}{[unused-imports]}
28
\li \l{Unresolved type}{[unresolved-type]}
29
\li \l{Unresolved Alias}{[unresolved-alias]}
30
\li \l{Missing enum entry}{[missing-enum-entry]}
31
\li \l{Missing property}{[missing-property]}
32
\li \l{Missing type}{[missing-type]}
33
\endlist
34
35
\section1 Prepare the project for qt_add_qml_module
36
37
\section2 Make qt_add_qml_module available in CMake
38
39
To make \l qt_add_qml_module available in CMake, add \c Core and \c Qml to your \c find_package
40
call in the project's top-level \c CMakeLists.txt file:
41
\badcode
42
find_package(Qt6 REQUIRED COMPONENTS Core Qml)
43
\endcode
44
45
\section2 Use qt_standard_project_setup
46
47
\l qt_standard_project_setup sets up \l{Qt CMake policies} needed for \l qt_add_qml_module, among
48
other things.
49
50
Call \l qt_standard_project_setup in the project's top-level \c CMakeLists.txt file
51
before any \l qt_add_qml_module call:
52
\badcode
53
qt_standard_project_setup(REQUIRES 6.8)
54
\endcode
55
56
\section1 Use qt_add_qml_module
57
58
\l qt_add_qml_module is the CMake function that takes care of generating QML modules. It
59
automatically generates \c qmldir and \c qmltypes files, and sets up tooling like \l qmlcachegen
60
or \l qmllint.
61
62
QML modules can be added to both executable and library targets in CMake. QML modules attached
63
to the executable target can't be used or linked by other executables, while QML modules attached
64
to library targets can.
65
66
\section2 Add a QML module to your executable target
67
In this case, the source files of the QML module are treated as part of the executable itself,
68
rather than being compiled into a separate library. This means neither a module nor plugin library
69
for this module is created—--the module is fully integrated into the executable. As a result, the
70
module is tied to that specific program and cannot be reused by other executables or libraries.
71
72
To add a QML module to your executable, in your \c CMakeLists.txt:
73
\badcode
74
# pre-existing:
75
qt_add_executable(MyApp main.cpp)
76
77
# add this
78
qt_add_qml_module(MyApp
79
URI MyAppModule
80
QML_FILES
81
Main.qml # and possibly more .qml files
82
)
83
\endcode
84
85
The \c Main.qml should start with an upper case letter so that it can be instantiated by
86
\c loadFromModule methods like \l{QQmlApplicationEngine::loadFromModule} or
87
\l{QQmlComponent::loadFromModule}.
88
Also, the QML module URI should be different from the target name to avoid name clashes
89
in the build folder.
90
91
\section2 Add a QML module to your library target
92
To add a QML module to your library, in your \c CMakeLists.txt:
93
\badcode
94
qt_add_qml_module(MyQmlLibrary
95
URI MyQmlModule
96
QML_FILES MyQmlComponent1.qml MyQmlComponent2.qml...
97
SOURCES MyCppComponent1.h MyCppComponent1.cpp MyCppComponent2.h MyCppComponent2.cpp...
98
RESOURCES MyResource1.png MyResource2.png...
99
)
100
\endcode
101
102
\l qt_add_qml_module creates a \c SHARED library via \l qt_add_library if the \c
103
MyQmlLibrary target does not exist yet, like in this example.
104
105
\note Your QML module URI should be different from the target name to avoid name clashes in the
106
build folder.
107
108
\section1 Use loadFromModule to load your QML files
109
110
Use \c loadFromModule to load your QML file, for example:
111
\badcode
112
engine.load(QUrl(QStringLiteral("qrc:/MyQmlModule/Main.qml")));
113
// becomes
114
engine.loadFromModule("MyQmlModule", "Main");
115
\endcode
116
117
\section1 Remove handwritten qmldir files
118
119
\l qt_add_qml_module automatically generates \c qmldir files. If you have singletons in
120
your \c qmldir, declare them in your \c CMakeLists.txt before the \l qt_add_qml_module call with:
121
\badcode
122
set_source_files_properties(MySingleton.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE)
123
\endcode
124
125
Delete the handwritten \c qmldir after that.
126
127
\section1 Remove qmltypes files generated by qmlplugindump
128
129
\l qt_add_qml_module auto-generates \c qmltypes files when all your types are using
130
\l{Registering C++ Types with the QML Type System}{declarative type registration}, which removes
131
the need to generate \c qmltypes files by hand using tools like \c qmlplugindump.
132
133
To achieve that, remove manual calls to \c qmlRegisterType and its variants. Then,
134
\l{Registering C++ Types with the QML Type System}{register your types declaratively} by using
135
\l QML_ELEMENT, for example:
136
\badcode
137
// add this header
138
#include <QtQml/qqmlregistrations.h>
139
140
class MyComponent: public QObject {
141
Q_OBJECT
142
143
// add this line to register MyComponent as 'MyComponent' in QML.
144
QML_ELEMENT
145
....
146
};
147
\endcode
148
149
See \l{Registering C++ Types with the QML Type System} on how to handle more complicated
150
registration cases like foreign type registration.
151
152
Delete the handwritten \c qmltypes files after that.
153
154
\section1 Remove handwritten type registration plugins
155
156
\l qt_add_qml_module can generate a \l {Creating C++ Plugins for QML}{QML module plugin}
157
automatically for you. You don't need a handwritten plugin if your plugin's only task is to do type
158
registration. Remove the plugin altogether if switching to declarative type registration did remove
159
all the code from your plugin.
160
161
Make sure that you \e remove the \c NO_PLUGIN, \c NO_PLUGIN_OPTIONAL, \c
162
NO_CREATE_PLUGIN_TARGET, and \c NO_GENERATE_PLUGIN_SOURCE arguments from \l qt_add_qml_module to
163
allow automatic plugin generation.
164
165
\section1 Remove qrc files
166
167
\l qt_add_qml_module automatically generates \c qrc files. To list resources in the \c qrc files,
168
like images or sound files, add them to \l{qt_add_qml_module}'s \c RESOURCES argument.
169
You can find the Module's resources under \c{:/qt/qml/MyQmlLibraryModule/}.
170
171
\section1 Replace directory imports with QML module imports
172
173
Replace directory imports with QML module imports. For example,
174
\badcode
175
import "content" // contains SomeType.qml
176
// becomes
177
import MyQmlModule // contains SomeType.qml
178
179
SomeType {
180
...
181
}
182
\endcode
183
184
Note that files inside a QML module automatically import their own QML module. You can remove the
185
self-imports.
186
187
\sa {Changes to Qt QML}, {Modern QML modules}
188
*/
qtdeclarative
src
qml
doc
src
qt6-port-to-qt-add-qml-module.qdoc
Generated on
for Qt by
1.14.0