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
qt_add_qml_module.qdoc
Go to the documentation of this file.
1
// Copyright (C) 2021 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
3
4
/*!
5
\page qt-add-qml-module.html
6
\ingroup cmake-commands-qtqml
7
8
\title qt_add_qml_module
9
\keyword qt6_add_qml_module
10
11
\summary{Defines a QML module.}
12
13
\cmakecommandsince 6.2
14
15
\include cmake-find-package-qml.qdocinc
16
17
\section1 Synopsis
18
19
\badcode
20
qt_add_qml_module(
21
target
22
URI uri
23
[VERSION version]
24
[PAST_MAJOR_VERSIONS ...]
25
[STATIC | SHARED]
26
[PLUGIN_TARGET plugin_target]
27
[OUTPUT_DIRECTORY output_dir]
28
[RESOURCE_PREFIX resource_prefix]
29
[CLASS_NAME class_name]
30
[TYPEINFO typeinfo]
31
[IMPORTS ...]
32
[OPTIONAL_IMPORTS ...]
33
[DEFAULT_IMPORTS ...]
34
[DEPENDENCIES ...]
35
[IMPORT_PATH ...]
36
[SOURCES ...]
37
[QML_FILES ...]
38
[RESOURCES ...]
39
[OUTPUT_TARGETS out_targets_var]
40
[DESIGNER_SUPPORTED]
41
[FOLLOW_FOREIGN_VERSIONING]
42
[NAMESPACE namespace]
43
[NO_PLUGIN]
44
[NO_PLUGIN_OPTIONAL]
45
[NO_CREATE_PLUGIN_TARGET]
46
[NO_GENERATE_PLUGIN_SOURCE]
47
[NO_GENERATE_QMLTYPES]
48
[NO_GENERATE_QMLDIR]
49
[NO_GENERATE_EXTRA_QMLDIRS]
50
[NO_GENERATE_QTCONF]
51
[NO_LINT]
52
[NO_CACHEGEN]
53
[NO_RESOURCE_TARGET_PATH]
54
[NO_IMPORT_SCAN]
55
[DISCARD_QML_CONTENTS]
56
[ENABLE_TYPE_COMPILER]
57
[TYPE_COMPILER_NAMESPACE namespace]
58
[QMLTC_EXPORT_DIRECTIVE export_macro]
59
[QMLTC_EXPORT_FILE_NAME header_defining_export_macro]
60
61
)
62
63
\endcode
64
65
\versionlessCMakeCommandsNote qt6_add_qml_module()
66
67
See \l {Building a QML application} and \l {Building a reusable QML module}
68
for examples that define QML modules.
69
70
\section1 Description
71
72
This command defines a QML module that can consist of C++ sources, \c{.qml}
73
files, or both. It ensures that essential module details are provided and that
74
they are consistent. It also sets up and coordinates things like cached
75
compilation of \c{.qml} sources, resource embedding, linting checks, and
76
auto-generation of some key module files.
77
78
For a conceptual overview with common usage examples, see
79
\l{Tying it all together with CMake}. For advanced topics like custom
80
directory layouts and versioning, see \l{Writing QML Modules}.
81
82
\section2 Target Structure
83
84
A QML module can be structured in a few different ways. The following scenarios
85
are the typical arrangements:
86
87
\section3 Separate backing and plugin targets
88
89
This is the recommended arrangement for most QML modules. All of the module's
90
functionality is implemented in the \e backing target, which is given as the
91
first command argument. C++ sources, \c{.qml} files, and resources should all
92
be added to the backing target. The backing target is a library that should be
93
installed in the same location as any other library defined by the project.
94
95
The source directory structure under which the backing target is created should
96
match the target path of the QML module (the target path is the module's URI
97
with dots replaced by forward slashes). If the source directory structure
98
doesn't match the target path, \c{qt_add_qml_module()} will issue a warning.
99
100
The following example shows a suitable source directory structure for a QML
101
module with a URI of \c{MyThings.Panels}. The call to \c{qt_add_qml_module()}
102
would be in the \c{CMakeLists.txt} file shown.
103
104
\badcode
105
src
106
+-- MyThings
107
+-- Panels
108
+-- CMakeLists.txt
109
\endcode
110
111
A separate \e plugin target is associated with the QML module. It is used at
112
runtime to load the module dynamically when the application doesn't already
113
link to the backing target. The plugin target will also be a library and is
114
normally installed to the same directory as the module's
115
\l{Module Definition qmldir Files}{qmldir} file.
116
117
The plugin target should ideally contain nothing more than a trivial
118
implementation of the plugin class. This allows the plugin to be designated as
119
optional in the \c qmldir file. Other targets can then link directly to the
120
backing target and the plugin will not be needed at runtime, which can improve
121
load-time performance. By default, a C++ source file that defines a minimal
122
plugin class will be automatically generated and added to the plugin target.
123
For cases where the QML module needs a custom plugin class implementation, the
124
\l{NO_GENERATE_PLUGIN_SOURCE} and usually the \l{NO_PLUGIN_OPTIONAL} options
125
will be needed.
126
127
The \c STATIC QML modules also generate the static QML plugins if
128
\c NO_PLUGIN is not specified. Targets that import such \c STATIC QML modules
129
also need to explicitly link to corresponding QML plugins.
130
131
\note
132
When using static linking, it might be necessary to use
133
\l {Q_IMPORT_QML_PLUGIN} to ensure that the QML plugin is correctly linked.
134
135
\section3 Plugin target with no backing target
136
137
A QML module can be defined with the plugin target serving as its own backing
138
target. In this case, the module must be loaded dynamically at runtime and
139
cannot be linked to directly by other targets. To create this arrangement,
140
the \c PLUGIN_TARGET keyword must be used, with the \c target repeated as the
141
plugin target name. For example:
142
143
\badcode
144
qt_add_qml_module(someTarget
145
PLUGIN_TARGET someTarget
146
...
147
)
148
\endcode
149
150
While this arrangement may seem marginally simpler to deploy, a separate
151
backing target should be preferred where possible due to the potentially better
152
load-time performance.
153
154
\section3 Executable as a QML module
155
156
An executable target can act as a backing target for a QML module. In this case,
157
there will be no plugin library, since the QML module will always be loaded
158
directly as part of the application. The \c{qt_add_qml_module()} command will
159
detect when an executable is used as the backing target and will automatically
160
disable the creation of a separate plugin. Do not use any of the options with
161
\c{PLUGIN} in their name when using this arrangement.
162
163
When an executable is used as the backing target, the source directory structure
164
is not expected to match the QML module's target path.
165
See \l{qmlcachegen-auto}{Caching compiled QML sources} for additional target
166
path differences for compiled-in resources.
167
168
169
\target qmldir-autogeneration
170
\section2 Auto-generating \c{qmldir} and typeinfo files
171
172
By default, a \l{Module Definition qmldir Files}{qmldir} file and a typeinfo
173
file will be auto-generated for the QML module being defined. The contents of
174
those files are determined by the various arguments given to this command, as
175
well as the sources and \c{.qml} files added to the backing target.
176
The \l OUTPUT_DIRECTORY argument determines where the \c qmldir and typeinfo
177
files will be written to. If the QML module has a plugin, that plugin will also
178
be created in the same directory as the \c qmldir file.
179
180
If \l{QTP0004} policy is set to \c NEW, for each further directory that contains
181
\c{.qml} files another \c qmldir file is generated. These extra \c qmldir files
182
merely redirect to the module's base directory via a \c prefer directive. This
183
is so that all the QML components in a module can access each other, no matter
184
which directory they are stored in.
185
186
If using a statically built Qt, the backing target's \c{.qml} files will be
187
scanned during the CMake configure run to determine the imports used by the
188
module and to set up linking relationships (the \c{NO_IMPORT_SCAN} keyword
189
can be given to disable this). When a \c{.qml} file is added to or
190
removed from the module, CMake will normally re-run automatically and the
191
relevant files will be re-scanned, since a \c{CMakeLists.txt} file will have
192
been modified. During the course of development, an existing \c{.qml} file may
193
add or remove an import or a type. On its own, this would not cause CMake to
194
re-run automatically, so you should explicitly re-run CMake to force the
195
\c qmldir file to be regenerated and any linking relationships to be updated.
196
197
The backing target's C++ sources are scanned at build time to generate a
198
typeinfo file and a C++ file to register the associated types. The generated
199
C++ file is automatically added to the backing target as a source.
200
This requires \c AUTOMOC to be enabled on the target. The project is
201
responsible for ensuring this, usually by setting the \c CMAKE_AUTOMOC variable
202
to \c TRUE before calling \c qt_add_qml_module(), or by passing in an existing
203
target with the \c AUTOMOC target property already set to \c TRUE. It isn't an
204
error to have \c AUTOMOC disabled on the target, but the project is then
205
responsible for handling the consequences. This may include having to manually
206
generate the typeinfo file instead of allowing it to be auto-generated with
207
missing details, and adding C++ code to register the types.
208
209
Projects should prefer to use the auto-generated typeinfo and \c qmldir files
210
where possible. They are easier to maintain and they don't suffer from the same
211
susceptibility to errors that hand-written files do. Nevertheless, for
212
situations where the project needs to provide these files itself, the
213
auto-generation can be disabled. The \c NO_GENERATE_QMLDIR option disables the
214
\c qmldir auto-generation and the \c NO_GENERATE_QMLTYPES option disables the
215
typeinfo and C++ type registration auto-generation. If the auto-generated
216
typeinfo file is acceptable, but the project wants to use a different name for
217
that file, it can override the default name with the \c TYPEINFO option (but
218
this should not typically be needed).
219
220
\target qmlcachegen-auto
221
\section2 Caching compiled QML sources
222
223
All \c{.qml}, \c{.js}, and \c{.mjs} files added to the module via the
224
\c QML_FILES argument will be compiled to bytecode and cached directly in the
225
backing target. This improves load-time performance of the module. The original
226
uncompiled files are also stored in the backing target's resources, as these
227
may still be needed in certain situations by the QML engine.
228
229
The resource path of each file is determined by its path relative to the
230
current source directory (\c CMAKE_CURRENT_SOURCE_DIR). This resource path is
231
appended to a prefix formed by concatenating the \l{RESOURCE_PREFIX} and
232
the target path (but see \l NO_RESOURCE_TARGET_PATH for an exception to this).
233
234
If \l{QTP0001} policy is set to \c NEW, the \l{RESOURCE_PREFIX} defaults
235
to \c{/qt/qml/} which is the default import path of the QML engine.
236
This ensures that modules are put into the \l{QML Import Path} and can be
237
found without further setup.
238
239
Ordinarily, the project should aim to place \c{.qml} files in
240
the same relative location as they would have in the resources. If the \c{.qml}
241
file is in a different relative directory to its desired resource path, its
242
location in the resources needs to be explicitly specified. This is done by
243
setting the \c QT_RESOURCE_ALIAS source file property, which must be set before
244
the \c{.qml} file is added. For example:
245
246
\badcode
247
set_source_files_properties(path/to/somewhere/MyFrame.qml PROPERTIES
248
QT_RESOURCE_ALIAS MyFrame.qml
249
)
250
251
qt_add_qml_module(someTarget
252
URI MyCo.Frames
253
RESOURCE_PREFIX /my.company.com/imports
254
QML_FILES
255
path/to/somewhere/MyFrame.qml
256
AnotherFrame.qml
257
)
258
\endcode
259
260
In the above example, the target path will be \c{MyCo/Frames}. After
261
taking into account the source file properties, the two \c{.qml} files will be
262
found at the following resource paths:
263
264
\list
265
\li \c{/my.company.com/imports/MyCo/Frames/MyFrame.qml}
266
\li \c{/my.company.com/imports/MyCo/Frames/AnotherFrame.qml}
267
\endlist
268
269
In the rare case that you want to override the automatic selection of the
270
qmlcachegen program to be used, you may set the \c QT_QMLCACHEGEN_EXECUTABLE
271
target property on the module target. For example:
272
273
\badcode
274
set_target_properties(someTarget PROPERTIES
275
QT_QMLCACHEGEN_EXECUTABLE qmlcachegen
276
)
277
\endcode
278
279
This explicitly selects qmlcachegen as the program to be used, even if
280
better alternatives are available.
281
282
Furthermore, you can pass extra arguments to qmlcachegen, by setting the
283
\c QT_QMLCACHEGEN_ARGUMENTS option. In particular, the \c --only-bytecode
284
option will turn off compilation of QML script code to C++. For example:
285
286
\badcode
287
set_target_properties(someTarget PROPERTIES
288
QT_QMLCACHEGEN_ARGUMENTS "--only-bytecode"
289
)
290
\endcode
291
292
Another important argument is \c{--direct-calls}. You can use it to enable the
293
direct mode of \l{The QML script compiler} in case the Qt Quick Compiler
294
Extensions are installed. If the extensions are not installed, the argument is
295
ignored. There is a shorthand called \c {QT_QMLCACHEGEN_DIRECT_CALLS} for it.
296
297
\badcode
298
set_target_properties(someTarget PROPERTIES
299
QT_QMLCACHEGEN_DIRECT_CALLS ON
300
)
301
\endcode
302
303
Finally, the \c --verbose argument can be used to see diagnostic output from
304
qmlcachegen:
305
306
\badcode
307
set_target_properties(someTarget PROPERTIES
308
QT_QMLCACHEGEN_ARGUMENTS "--verbose"
309
)
310
\endcode
311
312
With this flag set, qmlcachegen will output warnings for each function it
313
cannot compile to C++. Some of these warnings will point to problems in your
314
QML code and some will tell you that certain features of the QML language are
315
not implemented in the C++ code generator. In both cases, qmlcachegen will
316
still generate byte code for such functions. If you want to see only the
317
problems in your QML code, you should use qmllint and the targets generated
318
for it instead.
319
320
\target qmllint-auto
321
\section2 Linting QML sources
322
323
A separate linting target will be automatically created if any \c{.qml} files
324
are added to the module via the \c QML_FILES keyword, or by a later call to
325
\l{qt6_target_qml_sources}{qt_target_qml_sources()}. The name of the linting
326
target will be the \c target followed by \c{_qmllint}. An \c{all_qmllint}
327
target which depends on all the individual \c{*_qmllint} targets is also
328
provided as a convenience.
329
330
A \c dump_qml_context_properties global build target is automatically created
331
that runs \l qmlcontextpropertydump when no qml context property dump file
332
already exists. \l qmlcontextpropertydump creates a qml context property dump file
333
that is read by \l qmllint to warn about usages of context properties in QML.
334
335
A \c clean_qml_context_properties global build target allows to delete an already
336
existing qml context property dump file, and can be used to recompute the qml context
337
property dump file on a future build of the \c dump_qml_context_properties global build
338
target.
339
340
Linting targets depend on the \c dump_qml_context_properties build target when
341
the \l QT_QMLLINT_CONTEXT_PROPERTY_DUMP variable is enabled.
342
343
344
\target qml-naming-js-files
345
\section2 Naming conventions for \c{.js} files
346
347
JavaScript file names that are intended to be addressed as components should
348
start with an uppercase letter.
349
350
Alternatively, you may use lowercase file names and set the source file
351
property \l QT_QML_SOURCE_TYPENAME to the desired type name.
352
353
\target qml-cmake-singletons
354
\section2 Singletons
355
356
If a QML module has \c{.qml} files which provide singleton types, these files
357
need to have their \c QT_QML_SINGLETON_TYPE source property set to \c TRUE, to
358
ensure that the \c singleton command is written into the
359
\l{Module Definition qmldir Files}{qmldir} file. This must be done in addition
360
to the QML file containing the \c {pragma Singleton} statement.
361
The source property must be set before creating the module the
362
singleton belongs to.
363
364
See \l{qt_target_qml_sources_example}{qt_target_qml_sources()} for an example on
365
how to set the \c QT_QML_SINGLETON_TYPE property.
366
367
\target qmltc-cmake
368
\section2 Compiling QML to C++ with QML type compiler
369
370
\note The \l{QML type compiler} \c{qmltc} does not guarantee that the generated
371
C++ stays API-, source- or binary-compatible between past or future versions,
372
even patch versions.
373
Furthermore, qmltc-compiled apps using Qt's QML modules will require linking
374
against private Qt API, see also
375
\l{QML type compiler#compiling-qml-code-with-qmltc}{Compiling QML code with qmltc}.
376
377
378
If a QML module has \c{.qml} files, you can compile them to C++ using \l{QML
379
type compiler}{qmltc}. Unlike \l{qmlcachegen-auto}{bytecode compilation}, you
380
have to explicitly enable qmltc via \l{ENABLE_TYPE_COMPILER} argument. In which
381
case, \c{.qml} files specified under \c{QML_FILES} would be compiled. Files
382
ending with \c{.js} and \c{.mjs} are ignored as qmltc does not compile
383
JavaScript code. Additionally, files marked with QT_QML_SKIP_TYPE_COMPILER
384
source file property are also skipped.
385
386
By default, qmltc creates lower-case \c{.h} and \c{.cpp} files for a given
387
\c{.qml} file. For example, \c{Foo.qml} ends up being compiled into \c{foo.h}
388
and \c{foo.cpp}.
389
390
The created C++ files are placed into a dedicated \c{.qmltc/<target>/}
391
sub-directory of the \c BINARY_DIR of the \c target. These files are then
392
automatically added to the target sources and compiled as Qt C++ code along with
393
other source files.
394
395
While processing QML_FILES, the following source file properties are respected:
396
\list
397
\li \c{QT_QMLTC_FILE_BASENAME}: use this source file property to specify a
398
non-default .h and .cpp file name, which might be useful to e.g. resolve
399
conflicting file names (imagine you have main.qml that is being
400
compiled, but main.h already exists, so #include "main.h" might not do
401
what you expect it to do). QT_QMLTC_FILE_BASENAME is expected to be a
402
file name (without extension), so any preceding directory is ignored.
403
Unlike in the case of default behavior, the QT_QMLTC_FILE_BASENAME is
404
not lower-cased.
405
\li \c{QT_QML_SKIP_TYPE_COMPILER}: use this source file property to
406
specify that a QML file must be ignored by qmltc.
407
\endlist
408
409
\section1 Arguments
410
411
The arguments to \c{qt_add_qml_module} are organized into the following
412
categories:
413
414
\table
415
\header
416
\li Category
417
\li Arguments
418
\row
419
\li \l{Essential arguments}
420
\li \c target, \c URI, \c STATIC, \c SHARED
421
\row
422
\li \l{Versions}
423
\li \c VERSION, \l{PAST_MAJOR_VERSIONS},
424
\l{Keeping module versions in sync}{FOLLOW_FOREIGN_VERSIONING}
425
\row
426
\li \l{Adding sources and resources to the module}{Sources and resources}
427
\li \c QML_FILES, \c SOURCES, \c RESOURCES, \l{RESOURCE_PREFIX}, \l{NO_RESOURCE_TARGET_PATH},
428
\l{DISCARD_QML_CONTENTS}
429
\row
430
\li \l{Declaring module dependencies}{Module dependencies}
431
\li \l{IMPORTS}, \c OPTIONAL_IMPORTS, \c DEFAULT_IMPORTS, \c DEPENDENCIES,
432
\l{IMPORT_PATH}
433
\row
434
\li \l{Targets and plugin targets}{Plugin configuration}
435
\li \l{PLUGIN_TARGET}, \l{NO_PLUGIN}, \l{NO_PLUGIN_OPTIONAL},
436
\l{NO_CREATE_PLUGIN_TARGET}, \l{NO_GENERATE_PLUGIN_SOURCE},
437
\l{CLASS_NAME}
438
\row
439
\li \l{Automatic type registration}{Code generation and tooling}
440
\li \c NO_GENERATE_QMLTYPES, \c NO_GENERATE_QMLDIR, \c NO_GENERATE_EXTRA_QMLDIRS,
441
\c TYPEINFO, \c NO_CACHEGEN, \c NO_LINT,
442
\l{qmlimportscanner and NO_IMPORT_SCAN}{NO_IMPORT_SCAN}
443
\row
444
\li \l{OUTPUT_DIRECTORY}{Output and installation}
445
\li \l{OUTPUT_DIRECTORY}, \c OUTPUT_TARGETS, \l{NO_GENERATE_QTCONF}
446
\row
447
\li \l{C++ namespaces of generated code}{Other}
448
\li \c NAMESPACE, \c DESIGNER_SUPPORTED
449
\row
450
\li \l{Arguments for qmltc}{QML type compiler (qmltc)}
451
\li \l{ENABLE_TYPE_COMPILER}, \c TYPE_COMPILER_NAMESPACE,
452
\c QMLTC_EXPORT_DIRECTIVE, \c QMLTC_EXPORT_FILE_NAME
453
\endtable
454
455
\section2 Essential arguments
456
457
The \c target specifies the name of the backing target for the QML module.
458
By default, it is created as a shared library if Qt was built as shared
459
libraries, or as a static library otherwise. This choice can be explicitly
460
overridden with the \c STATIC or \c SHARED options.
461
462
Every QML module must define a \c URI. It should be specified in dotted URI
463
notation, such as \c{QtQuick.Layouts}. Each segment must be a well-formed
464
ECMAScript Identifier Name. This means, for example, the segments
465
must not start with a number and they must not contain \e{-} (minus)
466
characters. As the \c URI will be translated into directory names, you
467
should restrict it to alphanumeric characters of the latin alphabet,
468
underscores, and dots. Other QML modules may use this name in
469
\l{qtqml-syntax-imports.html}{import statements} to import the module. The
470
\c URI will be used in the \c module line of the generated
471
\l{Module Definition qmldir Files}{qmldir} file. The \c URI is also used to
472
form the \e{target path} by replacing dots with forward slashes.
473
474
See \l{qtqml-modules-identifiedmodules.html}{Identified Modules} for further
475
in-depth discussion of the module URI.
476
477
\section2 Versions
478
479
A QML module can also define a \c VERSION in the form \c{Major.Minor}, where
480
both \c Major and \c Minor must be integers. An additional \c{.Patch}
481
component may be appended, but will be ignored. A list of earlier major
482
versions the module provides types for can also optionally be given after the
483
\c PAST_MAJOR_VERSIONS keyword (see below).
484
See \l{qtqml-modules-identifiedmodules.html}{Identified Modules} for further
485
in-depth discussion of version numbering,
486
\l{Registering past major versions} for registering past major versions, and
487
\l{Keeping module versions in sync} for keeping module versions in sync.
488
489
If you don't need versions you should omit the \c VERSION argument. It defaults
490
to the highest possible version. Internal versioning of QML modules has some
491
fundamental flaws. You should use an external package management mechanism to
492
manage different versions of your QML modules.
493
494
\section2 Adding sources and resources to the module
495
496
\note A QML module is a logically grouped, self-contained unit of functionality.
497
All files that make up the module should reside in the same directory as the CMakeLists.txt
498
defining the module or in one of its subdirectories.
499
If a specific functionality is required in multiple modules, consider encapsulating it within
500
a separate module. This module can then be imported into other modules, promoting code reuse
501
and maintainability.
502
503
\c SOURCES specifies a list of non-QML sources to be added to the backing
504
target. It is provided as a convenience and is equivalent to adding the sources
505
to the backing target with the built-in \c{target_sources()} CMake command.
506
507
\c QML_FILES lists the \c{.qml}, \c{.js} and \c{.mjs} files for the module.
508
These will be automatically \l{qmlcachegen-auto}{compiled into bytecode} and
509
embedded in the backing target unless the \c NO_CACHEGEN option is given.
510
The uncompiled file is always stored in the embedded resources of the backing
511
target, even if \c NO_CACHEGEN is specified. Unless the \c NO_LINT option is
512
given, the uncompiled files will also be
513
\l{Linting QML sources}{processed by \c qmllint} via a separate custom build
514
target. The files will also be used to populate type information in the
515
generated \l{Module Definition qmldir Files}{qmldir} file by default.
516
\c NO_GENERATE_QMLDIR can be given to disable the automatic generation of the
517
\c qmldir file. This should normally be avoided, but for cases where the
518
project needs to provide its own \c qmldir file, this option can be used.
519
Since Qt 6.8, when \l{QTP0004} is enabled, \c qt_add_qml_module will
520
create additional \c qmldir files for each subdirectory in the QML module,
521
which ensure that each QML file will import its own module via the implicit
522
import. This behavior can be turned off for a QML module by passing the
523
\c NO_GENERATE_EXTRA_QMLDIRS flag to it.
524
The \c NO_GENERATE_QMLDIR implies \c NO_GENERATE_EXTRA_QMLDIRS.
525
526
\note See \l{qt6_target_qml_sources}{qt_target_qml_sources()} for further details on
527
how to add qmlfiles after \c qt_add_qml_module() was called.
528
For example, you may wish to add files conditionally based on an if statement
529
expression, or from subdirectories that will only be added if certain criteria
530
are met.
531
Furthermore, files added with \l{qt6_target_qml_sources}{qt_target_qml_sources()}
532
also can specify if they should be skipped for the linting,
533
\l{qmlcachegen-auto}{bytecode compilation} or \c qmldir file generation.
534
535
\c RESOURCES lists any other files needed by the module, such as images
536
referenced from the QML code. These files will be added as compiled-in
537
resources (see \l RESOURCE_PREFIX for an explanation of the base point they
538
will be located under). If needed, their relative location can
539
be controlled by setting the \c QT_RESOURCE_ALIAS source property, just as for
540
\c{.qml} files (see \l{qmlcachegen-auto}{Caching compiled QML sources}).
541
542
\target RESOURCE_PREFIX
543
\c RESOURCE_PREFIX is intended to encapsulate a namespace for the project and
544
will often be the same for all QML modules that the project defines.
545
546
However, it is better to set the \l QTP0001 CMake policy instead. It defines a
547
default resource prefix that ensures that your QML module ends
548
up under one of the QML engine's default \l[QtQml]{QML Import Path}{import paths}.
549
550
If you set a \c RESOURCE_PREFIX, you should also add it to the
551
\l[QtQml]{QML Import Path}{import paths} for the QML Engine to find the QML module.
552
553
If \l QTP0001 is enabled (e.g. via
554
\c {qt_standard_project_setup(REQUIRES 6.5)}), the default value is
555
\c "/qt/qml/", otherwise it is \c {"/"}.
556
557
\target NO_RESOURCE_TARGET_PATH
558
When various files are added to the compiled-in resources, they are placed
559
under a path formed by concatenating the \c RESOURCE_PREFIX and the target path.
560
For the special case where the backing target is an executable, it may be
561
desirable to place the module's \c{.qml} files and other resources directly
562
under the \c RESOURCE_PREFIX instead. This can be achieved by specifying the
563
\c NO_RESOURCE_TARGET_PATH option, which may only be used if the backing target
564
is an executable.
565
566
\note The resource path, the \l{OUTPUT_DIRECTORY}{output directory} on disk,
567
and the \l{IMPORT_PATH}{import path} are all related. When changing any of
568
these, ensure the others are consistent so that the QML engine and tooling can
569
find the module. See \l{Custom Directory Layouts} in \l{Writing QML Modules} for
570
a complete explanation.
571
572
\target PAST_MAJOR_VERSIONS
573
\section2 Registering past major versions
574
575
\c PAST_MAJOR_VERSIONS contains a list of additional major version that the module
576
provides. For each of those versions and each QML file
577
without a \c QT_QML_SOURCE_VERSIONS setting an additional entry in the
578
\l{Module Definition qmldir Files}{qmldir} file will be generated to specify
579
the extra version. Furthermore, the generated module registration code will
580
register the past major versions using \l{qmlRegisterModule()} on the C++ side.
581
The module registration code is automatically generated for your QML module,
582
unless you specify \c{NO_GENERATE_QMLTYPES} (but use of this option is strongly
583
discouraged). Usage of \c PAST_MAJOR_VERSIONS adds some overhead when your
584
module is imported. You should increment the major version of your module as
585
rarely as possible. Once you can rely on all QML files importing this module to
586
omit the version in their imports, you can safely omit \c{PAST_MAJOR_VERSIONS}.
587
All the QML files will then import the latest version of your module. If you
588
have to support versioned imports, consider supporting only a limited number of
589
past major versions.
590
591
\section2 Declaring module dependencies
592
593
\target IMPORTS
594
\c IMPORTS provides a list of other QML modules that this module imports. Each
595
module listed here will be added as an \c{import} entry in the generated
596
\l{Module Definition qmldir Files}{qmldir} file. If a QML file imports
597
this module, it also imports all the modules listed under \c{IMPORTS}.
598
Optionally, a version can be specified by appending it after a slash, such as
599
\c{QtQuick/2.0}. Omitting the version will cause the greatest version available
600
to be imported. You may only specify the major version, as in \c{QtQuick/2}. In
601
that case the greatest minor version available with the given major version will
602
be imported. Finally, \c{auto} may be given as version (\c{QtQuick/auto}). If
603
\c{auto} is given, the version that the current module is being imported with is
604
propagated to the module to be imported. Given an entry \c{QtQuick/auto} in a
605
module \c{YourModule}, if a QML file specifies \c{import YourModule 3.14}, this
606
results in importing version \c{3.14} of \c{QtQuick}. For related modules that
607
follow a common versioning scheme, you should use \c{auto}.
608
609
Entries in \c IMPORTS may also refer to CMake targets by prefixing the target
610
name with the \c TARGET keyword. In this case, the QML module URI is determined
611
automatically from the target. This requires opting into the CMake policy
612
\l{QTP0005}.
613
614
For example, a QML module can import another module by referring to the
615
CMake target that provides it:
616
617
\badcode
618
qt_add_qml_module(my_module
619
URI MyModule
620
VERSION 1.0
621
IMPORTS
622
TARGET OtherQmlModule
623
)
624
\endcode
625
626
\c OPTIONAL_IMPORTS provides a list of other QML modules that this module
627
\e may import at run-time. These are not automatically imported by the QML
628
engine when importing the current module, but rather serve as hints to tools
629
like \c qmllint. Versions can be specified in the same way as for \c IMPORTS.
630
Each module listed here will be added as an \c{optional import} entry in the
631
generated \l{Module Definition qmldir Files}{qmldir} file.
632
633
Entries in \c OPTIONAL_IMPORTS may also refer to CMake targets by prefixing the
634
target name with the \c TARGET keyword. In this case, the QML module URI is
635
determined automatically from the target. This requires opting into the CMake
636
policy \l{QTP0005}.
637
638
For example:
639
640
\badcode
641
qt_add_qml_module(my_module
642
URI MyModule
643
VERSION 1.0
644
OPTIONAL_IMPORTS
645
TARGET OptionalQmlModule
646
)
647
\endcode
648
649
\c DEFAULT_IMPORTS specifies which of the optional imports are the default entries
650
that should be loaded by tooling. One entry should be specified for every group of
651
\c OPTIONAL_IMPORTS in the module. As optional imports are only resolved at runtime,
652
tooling like qmllint cannot in general know which of the optional imports should
653
be resolved. To remedy this, you can specify one of the optional imports as the
654
default import; tooling will then pick it. If you have one optional import that
655
gets used at runtime without any further configuration, that is an ideal candidate
656
for the default import.
657
658
Entries in \c DEFAULT_IMPORTS may also refer to CMake targets by prefixing the
659
target name with the \c TARGET keyword. In this case, the QML module URI is
660
determined automatically from the target. This requires opting into the CMake
661
policy \l{QTP0005}.
662
663
For example:
664
665
\badcode
666
qt_add_qml_module(my_module
667
URI MyModule
668
VERSION 1.0
669
OPTIONAL_IMPORTS
670
TARGET BackendA
671
TARGET BackendB
672
DEFAULT_IMPORTS
673
TARGET BackendA
674
)
675
\endcode
676
677
\c DEPENDENCIES provides a list of other QML modules that this module depends
678
on, but doesn't necessarily import. It would typically be used for dependencies
679
that only exist at the C++ level, such as a module registering a class to QML
680
which uses or inherits C++ defined types defined in another module.
681
682
For example, if one would like to subclass \c QQuickItem as following:
683
684
\badcode
685
class MyItem: public QQuickItem { ... };
686
\endcode
687
688
then one has to make sure that the module containing \c QQuickItem, called
689
\c QtQuick, is declared as a dependency via the \c DEPENDENCIES option:
690
691
\badcode
692
qt_add_qml_module(myTarget
693
...
694
DEPENDENCIES QtQuick
695
)
696
\endcode
697
698
Not doing so might result in linting errors, errors during type compilation
699
with \l{QML type compiler}{qmltc} or during binding and function compilation to C++
700
with \l{qmlcachegen-auto}{qmlcachegen}.
701
702
Another example might be:
703
\code
704
class MyComponent : public QObject {
705
Q_OBJECT
706
QML_ELEMENT
707
708
// ...
709
710
signals:
711
void sigZoomAtMousePosition(const QPointF& aMousePos, double aZoomScaleFactor);
712
};
713
\endcode
714
where \c{DEPENDENCIES QtQml} is required for QML tooling to find and use QPointF:
715
\badcode
716
qt_add_qml_module(myTarget
717
...
718
DEPENDENCIES QtQml
719
)
720
\endcode
721
722
Entries in \c DEPENDENCIES may also refer to CMake targets by prefixing the
723
target name with the \c TARGET keyword. In this case, the QML module URI and
724
import path are determined automatically from the target. This requires
725
opting into the CMake policy \l{QTP0005}.
726
727
For example, a QML module can declare a dependency on another module by
728
referring to the CMake target that provides it:
729
730
\badcode
731
qt_add_qml_module(my_module
732
URI MyModule
733
VERSION 1.0
734
DEPENDENCIES
735
TARGET OtherQmlModule
736
)
737
\endcode
738
739
\note Using \c{TARGET <cmake-target>} in \c DEPENDENCIES, \c IMPORTS,
740
\c OPTIONAL_IMPORTS, or \c DEFAULT_IMPORTS does not automatically link against
741
the given target. It is used only to derive QML metadata, import paths, and to
742
establish build-order dependencies. If the QML module or its generated plugin
743
requires symbols from that target, the target must still be linked explicitly
744
using \c target_link_libraries().
745
746
\note The \c{<cmake-target>} used with the \c TARGET keyword must be a target
747
built by your project (not an imported target provided by \c{find_package}).
748
749
\note When using \c{TARGET <cmake-target>} in \c DEPENDENCIES, \c IMPORTS,
750
\c OPTIONAL_IMPORTS, or \c DEFAULT_IMPORTS, only the direct dependency on the
751
specified target is established. Transitive QML module dependencies of the
752
referenced target (that is, QML modules which that target itself depends on)
753
are \e not automatically added. Each QML module dependency must be declared
754
explicitly.
755
756
\note Adding the module to \c DEPENDENCIES is not necessary if the module
757
is already imported via the \c IMPORTS option. The recommended way is to
758
use the lighter alternative \c DEPENDENCIES over \c IMPORTS.
759
760
\target NO_GENERATE_QTCONF
761
When the backing target is an executable and \c{TARGET} dependencies are used
762
(requires \l{QTP0005}), \c{qt_add_qml_module()} automatically generates a
763
\c{qt.conf} file next to the executable in the build tree. This file configures
764
the \l{QML Import Path} so that the QML engine can locate the module's
765
dependencies at run time without requiring manual \c IMPORT_PATH entries. The
766
\c NO_GENERATE_QTCONF option suppresses this behavior, which may be necessary
767
if the generated file conflicts with a \c qt.conf already present in the build
768
directory. This option was introduced in Qt 6.12.
769
770
\warning When using \c NO_GENERATE_QTCONF, the application may fail to find its
771
QML module dependencies at run time. You must manually configure the
772
\l{QML Import Path} — for example, by adding the appropriate import paths to
773
the existing \c qt.conf file.
774
775
The module version of the
776
dependencies must be specified along with the module name, in the same form as
777
used for \c IMPORTS and \c OPTIONAL_IMPORTS. Each module listed here will be
778
added as a \c{depends} entry in the generated
779
\l{Module Definition qmldir Files}{qmldir} file.
780
781
\target IMPORT_PATH
782
\c IMPORT_PATH can be used to add to the search paths where other QML modules
783
that this one depends on can be found. The other modules must have their
784
\c qmldir file under their own target path below one of the search paths.
785
786
If the backing target is a static library and that static library will be
787
installed, \c OUTPUT_TARGETS should be given to provide a variable in which to
788
store a list of additional targets that will also need to be installed.
789
These additional targets are generated internally by \c{qt_add_qml_module()}
790
and are referenced by the backing target's linking requirements as part of
791
ensuring that resources are set up and loaded correctly.
792
793
\target PLUGIN_TARGET
794
\section2 Targets and plugin targets
795
796
The following options control how the plugin target is created and configured.
797
For most modules, the defaults are appropriate and none of these options are
798
needed. Common scenarios:
799
800
\list
801
\li \b{Default} — a separate plugin target is created automatically with a
802
generated source file. The plugin is optional (not loaded when the backing
803
library is linked directly).
804
\li \b{Custom plugin} — use \l{NO_GENERATE_PLUGIN_SOURCE} to provide your own
805
plugin class implementation. You should also set \l{CLASS_NAME} to match
806
your custom plugin class. Typically also requires
807
\l{NO_PLUGIN_OPTIONAL} since the plugin then contains non-trivial code.
808
\li \b{No plugin} — use \l{NO_PLUGIN} when the module is always linked
809
directly and never loaded dynamically.
810
\li \b{Executable target} — no plugin is created automatically.
811
\endlist
812
813
\c PLUGIN_TARGET specifies the plugin target associated with the QML module.
814
The \c PLUGIN_TARGET can be the same as the backing
815
\c target, in which case there will be no separate backing target.
816
If \c PLUGIN_TARGET is not given, it defaults to \c target with \c plugin
817
appended. For example, a backing target called \c mymodule would have a default
818
plugin name of \c mymoduleplugin. The plugin target's name will be used to
819
populate a \c{plugin} line in the generated
820
\l{Module Definition qmldir Files}{qmldir} file. Therefore, you must not try to
821
change the plugin's output name by setting target properties like
822
\c OUTPUT_NAME or any of its related properties.
823
824
The backing \c target and the plugin target (if different) will be created by
825
the command, unless they already exist. Projects should generally let them be
826
created by the command so that they are created as the appropriate target type.
827
If the backing \c target is a static library, the plugin will also be created
828
as a static library. If the backing \c target is a shared library, the plugin
829
will be created as a module library. If an existing \c target is passed in and
830
it is an executable target, there will be no plugin. If you intend to always
831
link directly to the backing target and do not need a plugin, it can be
832
disabled by adding the \c NO_PLUGIN option. Specifying both \c NO_PLUGIN and
833
\c PLUGIN_TARGET is an error.
834
835
\target NO_CREATE_PLUGIN_TARGET
836
In certain situations, the project may want to delay creating the plugin target
837
until after the call. The \c NO_CREATE_PLUGIN_TARGET option can be given in
838
that situation. The project is then expected to call
839
\l{qt6_add_qml_plugin}{qt_add_qml_plugin()} on the plugin target once it has
840
been created. When \c NO_CREATE_PLUGIN_TARGET is given, \c PLUGIN_TARGET must
841
also be provided to explicitly name the plugin target.
842
843
\target CLASS_NAME
844
\target NO_GENERATE_PLUGIN_SOURCE
845
By default, \c{qt_add_qml_module()} will auto-generate a \c{.cpp} file that
846
implements the plugin class named by the \c CLASS_NAME argument. The generated
847
\c{.cpp} file will be automatically added to the plugin target as a source file
848
to be compiled. If the project wants to provide its own implementation of the
849
plugin class, the \c NO_GENERATE_PLUGIN_SOURCE option should be given. Where no
850
\c CLASS_NAME is provided, it defaults to the \c URI with dots replaced by
851
underscores, then \c Plugin appended. Unless the QML module has no plugin, the
852
class name will be recorded as a \c classname line in the generated
853
\l{Module Definition qmldir Files}{qmldir} file. You need to add any C++ files
854
with custom plugin code to the plugin target. Since the plugin then likely
855
contains functionality that goes beyond simply loading the backing library, you
856
will probably want to add \l{NO_PLUGIN_OPTIONAL}, too. Otherwise the QML engine
857
may skip loading the plugin if it detects that the backing library is already
858
linked.
859
860
\target NO_PLUGIN
861
If the \c NO_PLUGIN keyword is given, then no plugin will be built. This
862
keyword is thus incompatible with all the options that customize the plugin
863
target, in particular \l{NO_GENERATE_PLUGIN_SOURCE}, \l{NO_PLUGIN_OPTIONAL},
864
\l{PLUGIN_TARGET}, \l{NO_CREATE_PLUGIN_TARGET}, and \l{CLASS_NAME}. If you do
865
not provide a plugin for your module, it will only be fully usable if its
866
backing library has been linked into the executable. It is generally hard to
867
guarantee that a linker preserves the linkage to a library it considers unused.
868
869
\target NO_PLUGIN_OPTIONAL
870
If the \c NO_PLUGIN_OPTIONAL keyword is given, then the plugin is recorded in
871
the generated \c qmldir file as non-optional. If all of a QML module's
872
functionality is implemented in its backing target and the plugin target is
873
separate, then the plugin can be optional, which is the default and recommended
874
arrangement. The auto-generated plugin source file satisfies this requirement.
875
Where a project provides its own \c{.cpp} implementation for the plugin, that
876
would normally mean the \c NO_PLUGIN_OPTIONAL keyword is also needed because
877
the plugin will almost certainly contain functionality that the QML module
878
requires.
879
880
\section2 Automatic type registration
881
882
\c{qt_add_qml_module} automatically generates several files. The following
883
options control what is generated. In most cases, the defaults are correct and
884
none of these options are needed.
885
886
\table
887
\header
888
\li Option
889
\li What it disables
890
\row
891
\li \c NO_GENERATE_QMLTYPES
892
\li Typeinfo file (\c{.qmltypes}) and C++ type registration code
893
\row
894
\li \c NO_GENERATE_QMLDIR
895
\li The \c qmldir module definition file (implies \c NO_GENERATE_EXTRA_QMLDIRS)
896
\row
897
\li \c NO_GENERATE_EXTRA_QMLDIRS
898
\li Additional \c qmldir files for subdirectories (see \l{QTP0004})
899
\row
900
\li \c NO_CACHEGEN
901
\li Bytecode compilation of \c{.qml}, \c{.js}, and \c{.mjs} files
902
\row
903
\li \c NO_LINT
904
\li The \c{*_qmllint} linting target
905
\row
906
\li \l{qmlimportscanner and NO_IMPORT_SCAN}{NO_IMPORT_SCAN}
907
\li Automatic import scanning (static builds: configure-time; executables: build-time)
908
\endtable
909
910
Type registration is automatically performed for the backing target's C++
911
sources that are processed by \c{AUTOMOC}. This will generate a typeinfo file in
912
the \l{OUTPUT_DIRECTORY}{output directory}, the file name being the \c target
913
name with \c{.qmltypes} appended. This file name can be changed using the
914
\c TYPEINFO option if desired, but this should not normally be necessary.
915
The file name is also recorded as a \c typeinfo entry in the generated
916
\l{Module Definition qmldir Files}{qmldir} file. Automatic type registration
917
can be disabled using the \c NO_GENERATE_QMLTYPES option, in which case no
918
typeinfo file will be generated, but the project will still be expected to
919
generate a typeinfo file and place it in the same directory as the generated
920
\c qmldir file.
921
922
\target OUTPUT_DIRECTORY
923
\c OUTPUT_DIRECTORY specifies where the plugin library, \c qmldir and typeinfo
924
files are generated. When this keyword is not given, the default value will be
925
the target path (formed from the \c URI) appended to the value of the
926
\l QT_QML_OUTPUT_DIRECTORY variable.
927
If that variable is not defined, the default depends on the type of backing
928
target. For executables, the value will be the target path appended to
929
\c{${CMAKE_CURRENT_BINARY_DIR}}, whereas for other targets it will be just
930
\c{${CMAKE_CURRENT_BINARY_DIR}}. When the structure of the source tree
931
matches the structure of QML module target paths (which is highly recommended),
932
\l QT_QML_OUTPUT_DIRECTORY often isn't needed. In order to match the structure
933
of the target paths, you have to call your directories \e exactly like the
934
segments of your module URI. For example, if your module URI is
935
\c{MyUpperCaseThing.mylowercasething}, you need to put this in a directory
936
called \c{MyUpperCaseThing/mylowercasething/}.
937
938
The need for specifying the \c OUTPUT_DIRECTORY keyword should be rare, but if
939
it is used, it is likely that the caller will also need to add to the
940
\l IMPORT_PATH to ensure that \l{qmllint-auto}{linting},
941
\l{qmlcachegen-auto}{cached compilation} of qml sources,
942
\l{qt6_import_qml_plugins}{automatic importing} of plugins in static builds,
943
and \l{qt_deploy_qml_imports}{deploying imported QML modules} for non-static
944
builds all work correctly.
945
946
\section2 Qt Quick Designer compatibility
947
948
\c DESIGNER_SUPPORTED should be given if the QML module supports
949
Qt Quick Designer. When present, the generated \c qmldir file will contain
950
a \c designersupported line. See \l{Module Definition qmldir Files} for how
951
this affects the way Qt Quick Designer handles the plugin.
952
953
\section2 Keeping module versions in sync
954
955
The \c FOLLOW_FOREIGN_VERSIONING keyword relates to base types of your own
956
C++-defined QML types that live in different QML modules. Typically, the
957
versioning scheme of your module does not match that of the module providing
958
the base types. Therefore, by default all revisions of the base types are
959
made available in any import of your module. If \c FOLLOW_FOREIGN_VERSIONING
960
is given, the version information attached to the base types and their
961
properties is respected. So, an \c {import MyModule 2.8} will then only make
962
available versioned properties up to version \c{2.8} of any base types outside
963
\c{MyModule}.
964
This is mostly useful if you want to keep your module version in sync
965
with other modules you're basing types on. In that case you might want your custom
966
types to not expose properties from a module's base type version greater than the one being
967
imported.
968
969
\section2 C++ namespaces of generated code
970
971
If a namespace is given with the \c NAMESPACE keyword, the plugin and registration
972
code will be generated into a C++ namespace of this name.
973
974
\section2 qmlimportscanner and NO_IMPORT_SCAN
975
976
For static Qt builds, \c{qmlimportscanner} is run at configure time to scan the
977
\c{.qml} files of a QML module and identify the QML imports it uses (see
978
\l{qt6_import_qml_plugins}{qt_import_qml_plugins()}). For non-static Qt builds,
979
if the target is an executable, a similar scan is performed at build time to
980
provide the information needed by deployment scripts (see
981
\l{qt6_deploy_qml_imports}{qt_deploy_qml_imports()}). Both scans can be
982
disabled by providing the \c{NO_IMPORT_SCAN} option. Doing so means the project
983
takes on the responsibility of ensuring all required plugins are instantiated
984
and linked for static builds. For non-static builds the project must manually
985
work out and deploy all QML modules used by an executable target.
986
987
\section2 DISCARD_QML_CONTENTS
988
989
\target DISCARD_QML_CONTENTS
990
By default, QML and JS source file contents are included in the target's resource system.
991
Use \c DISCARD_QML_CONTENTS to remove these contents and reduce the binary size.
992
993
\note If you omit the source code from the binary, the QML engine has to
994
rely on the compilation units created by \l{qmlcachegen} or \l{qmlsc}.
995
Those are tied to the specific version of Qt they were built with. If you change
996
the version of Qt your application uses, they can't be loaded anymore.
997
998
\section2 Arguments for qmltc
999
1000
\target ENABLE_TYPE_COMPILER
1001
\c ENABLE_TYPE_COMPILER can be used to compile \c{.qml} files to C++ source code
1002
with \l{QML type compiler}{qmltc}. Files with the source property
1003
\c{QT_QML_SKIP_TYPE_COMPILER} are not compiled to C++.
1004
1005
\c TYPE_COMPILER_NAMESPACE argument allows to override the namespace in which
1006
\l{QML type compiler}{qmltc} generates code.
1007
By default, the namespace of the generated code follows the module
1008
hierarchy as depicted in the URI,
1009
e.g., \c MyModule for a module with URI \c MyModule or
1010
\c com::example::Module for URI \c com.example.MyModule.
1011
By specifying the \c TYPE_COMPILER_NAMESPACE option, the generated code
1012
can be put instead in a custom namespace, where different subnamespaces are to
1013
be separated by a "::", e.g. "MyNamespace::MySubnamespace" for the namespace MySubnamespace that
1014
is inside the MyNamespace. Apart from the "::", C++ namespace naming rules
1015
apply.
1016
1017
\c QMLTC_QMLTC_EXPORT_DIRECTIVE should be used with \c QMLTC_EXPORT_FILE_NAME when
1018
the classes generated by \l{QML type compiler}{qmltc} should be exported from
1019
the qml library. By default, classes generated by qmltc are not exported from
1020
their library.
1021
The header defining the export macro for the current library
1022
can be specified as an optional argument to \c QMLTC_EXPORT_FILE_NAME while the
1023
exporting macro name should be specified as an argument to
1024
\c QMLTC_QMLTC_EXPORT_DIRECTIVE. If no additional include is required or wanted,
1025
e.g. when the header of the export macro is already indirectly included by a base
1026
class, then the \c QMLTC_EXPORT_FILE_NAME option can be left out.
1027
*/
qtdeclarative
src
qml
doc
src
cmake
qt_add_qml_module.qdoc
Generated on
for Qt by
1.16.1