qt_add_qml_module( target URI uri VERSION version [PAST_MAJOR_VERSIONS ...] [STATIC | SHARED] [PLUGIN_TARGET plugin_target] [OUTPUT_DIRECTORY output_dir] [RESOURCE_PREFIX resource_prefix] [CLASS_NAME class_name] [TYPEINFO typeinfo] [IMPORTS ...] [OPTIONAL_IMPORTS ...] [DEPENDENCIES ...] [IMPORT_PATH ...] [SOURCES ...] [QML_FILES ...] [RESOURCES ...] [OUTPUT_TARGETS out_targets_var] [DESIGNER_SUPPORTED] [NO_PLUGIN_OPTIONAL] [NO_CREATE_PLUGIN_TARGET] [NO_GENERATE_PLUGIN_SOURCE] [NO_GENERATE_QMLTYPES] [NO_GENERATE_QMLDIR] [NO_LINT] [NO_CACHEGEN] [NO_RESOURCE_TARGET_PATH] )
若
无版本命令
被禁用,使用
qt6_add_qml_module()
代替。它支持如此命令的一组相同自变量。
This command defines a QML module that can consist of C++ sources,
.qml
files, or both. It ensures that essential module details are provided and that they are consistent. It also sets up and coordinates things like cached compilation of
.qml
sources, resource embedding, linting checks, and auto-generation of some key module files.
A QML module can be structured in a few different ways. The following scenarios are the typical arrangements:
This is the recommended arrangement for most QML modules. All of the module's functionality is implemented in the
backing
target, which is given as the first command argument. C++ sources,
.qml
files, and resources should all be added to the backing target. The backing target is a library that should be installed in the same location as any other library defined by the project.
The source directory structure under which the backing target is created should match the target path of the QML module (the target path is the module's URI with dots replaced by forward slashes). If the source directory structure doesn't match the target path,
qt_add_qml_module()
will issue a warning.
The following example shows a suitable source directory structure for a QML module with a URI of
MyThings.Panels
. The call to
qt_add_qml_module()
would be in the
CMakeLists.txt
file shown.
src +-- MyThings +-- Panels +-- CMakeLists.txt
单独 plugin target is associated with the QML module. It is used at runtime to load the module dynamically when the application doesn't already link to the backing target. The plugin target will also be a library and is normally installed to the same directory as the module's qmldir 文件。
The plugin target should ideally contain nothing more than a trivial implementation of the plugin class. This allows the plugin to be designated as optional in the
qmldir
file. Other targets can then link directly to the backing target and the plugin will not be needed at runtime, which can improve load-time performance. By default, a C++ source file that defines a minimal plugin class will be automatically generated and added to the plugin target. For cases where the QML module needs a custom plugin class implementation, the
NO_GENERATE_PLUGIN_SOURCE
and usually the
NO_PLUGIN_OPTIONAL
options will be needed.
A QML module can be defined with the plugin target serving as its own backing target. In this case, the module must be loaded dynamically at runtime and cannot be linked to directly by other targets. To create this arrangement, the
PLUGIN_TARGET
keyword must be used, with the
target
repeated as the plugin target name. For example:
qt_add_qml_module(someTarget PLUGIN_TARGET someTarget ... )
While this arrangement may seem marginally simpler to deploy, a separate backing target should be preferred where possible due to the potentially better load-time performance.
An executable target can act as a backing target for a QML module. In this case, there will be no plugin library, since the QML module will always be loaded directly as part of the application. The
qt_add_qml_module()
command will detect when an executable is used as the backing target and will automatically disable the creation of a separate plugin. Do not use any of the options with
PLUGIN
in their name when using this arrangement.
When an executable is used as the backing target, the source directory structure is not expected to match the QML module's target path. See 缓存编译的 QML 源 for additional target path differences for compiled-in resources.
qmldir
and typeinfo files
默认情况下,
qmldir
file and a typeinfo file will be auto-generated for the QML module being defined. The contents of those files are determined by the various arguments given to this command, as well as the sources and
.qml
files added to the backing target. The
OUTPUT_DIRECTORY
argument determines where the
qmldir
and typeinfo files will be written to. If the QML module has a plugin, that plugin will also be created in the same directory as the
qmldir
文件。
If using a statically built Qt, the backing target's
.qml
files will be scanned during the CMake configure run to determine the imports used by the module and set up linking relationships. When a
.qml
file is added to or removed from the module, CMake will normally re-run automatically and the relevant files will be re-scanned, since a
CMakeLists.txt
file will have been modified. During the course of development, an existing
.qml
file may add or remove an import or a type. On its own, this would not cause CMake to re-run automatically, so you should explicitly re-run CMake to force the
qmldir
file to be regenerated and any linking relationships to be updated.
The backing target's C++ sources are scanned at build time to generate a typeinfo file and a C++ file to register the associated types. The generated C++ file is automatically added to the backing target as a source. This requires
AUTOMOC
to be enabled on the target. The project is responsible for ensuring this, usually by setting the
CMAKE_AUTOMOC
变量到
TRUE
before calling
qt_add_qml_module()
, or by passing in an existing target with the
AUTOMOC
target property already set to
TRUE
. It isn't an error to have
AUTOMOC
disabled on the target, but the project is then responsible for handling the consequences. This may include having to manually generate the typeinfo file instead of allowing it to be auto-generated with missing details, and adding C++ code to register the types.
Projects should prefer to use the auto-generated typeinfo and
qmldir
files where possible. They are easier to maintain and they don't suffer from the same susceptibility to errors that hand-written files do. Nevertheless, for situations where the project needs to provide these files itself, the auto-generation can be disabled. The
NO_GENERATE_QMLDIR
option disables the
qmldir
auto-generation and the
NO_GENERATE_QMLTYPES
option disables the typeinfo and C++ type registration auto-generation. If the auto-generated typeinfo file is acceptable, but the project wants to use a different name for that file, it can override the default name with the
TYPEINFO
option (but this should not typically be needed).
所有
.qml
,
.js
,和
.mjs
files added to the module via the
QML_FILES
argument will be compiled to bytecode and cached directly in the backing target. This improves load-time performance of the module. The original uncompiled files are also stored in the backing target's resources, as these may still be needed in certain situations by the QML engine.
The resource path of each file is determined by its path relative to the current source directory (
CMAKE_CURRENT_SOURCE_DIR
). This resource path is appended to a prefix formed by concatenating the
RESOURCE_PREFIX
and the target path (but see
NO_RESOURCE_TARGET_PATH
for an exception to this). Ordinarily, the project should aim to place
.qml
files in the same relative location as they would have in the resources. If the
.qml
file is in a different relative directory to its desired resource path, its location in the resources needs to be explicitly specified. This is done by setting the
QT_RESOURCE_ALIAS
source file property, which must be set before the
.qml
file is added. For example:
set_source_files_properties(path/to/somewhere/MyFrame.qml PROPERTIES QT_RESOURCE_ALIAS MyFrame.qml ) qt_add_qml_module(someTarget URI MyCo.Frames RESOURCE_PREFIX /my.company.com/imports QML_FILES path/to/somewhere/MyFrame.qml AnotherFrame.qml )
In the above example, the target path will be
MyCo/Frames
. After taking into account the source file properties, the two
.qml
files will be found at the following resource paths:
/my.company.com/imports/MyCo/Frames/MyFrame.qml
/my.company.com/imports/MyCo/Frames/AnotherFrame.qml
A separate linting target will be automatically created if any
.qml
files are added to the module via the
QML_FILES
keyword, or by a later call to
qt_target_qml_sources()
. The name of the linting target will be the
target
followed by
_qmllint
. An
all_qmllint
target which depends on all the individual
*_qmllint
targets is also provided as a convenience.
target
specifies the name of the backing target for the QML module. By default, it is created as a shared library if Qt was built as shared libraries, or as a static library otherwise. This choice can be explicitly overridden with the
STATIC
or
SHARED
选项。
The plugin target associated with the QML module can be specified using the
PLUGIN_TARGET
自变量。
PLUGIN_TARGET
can be the same as the backing
target
, in which case there will be no separate backing target. If
PLUGIN_TARGET
不给定,默认为
target
with
plugin
appended. For example, a backing target called
mymodule
would have a default plugin name of
mymoduleplugin
. The plugin target's name will be used to populate a
plugin
line in the generated
qmldir
file. Therefore, you must not try to change the plugin's output name by setting target properties like
OUTPUT_NAME
or any of its related properties.
The backing
target
and the plugin target (if different) will be created by the command, unless they already exist. Projects should generally let them be created by the command so that they are created as the appropriate target type. If the backing
target
is a static library, the plugin will also be created as a static library. If the backing
target
is a shared library, the plugin will be created as a module library. If an existing
target
is passed in and it is an executable target, there will be no plugin. If you intend to always link directly to the backing target and do not need a plugin, it can be disabled by adding the
NO_PLUGIN
option. Specifying both
NO_PLUGIN
and
PLUGIN_TARGET
is an error.
In certain situations, the project may want to delay creating the plugin target until after the call. The
NO_CREATE_PLUGIN_TARGET
option can be given in that situation. The project is then expected to call
qt_add_qml_plugin()
on the plugin target once it has been created. When
NO_CREATE_PLUGIN_TARGET
有给定,
PLUGIN_TARGET
must also be provided to explicitly name the plugin target.
Every QML module must define a
URI
. It should be specified in dotted URI notation, such as
QtQuick.Layouts
. It must not contain anything other than alphanumeric or dot characters. Other QML modules may use this name in
import statements
to import the module. The
URI
will be used in the
模块
line of the generated
qmldir
file. The
URI
is also used to form the
target path
by replacing dots with forward slashes.
A QML module must also define a
VERSION
in the form
Major.Minor
, where both
Major
and
Minor
must be integers. An additional
.Patch
component may be appended, but will be ignored. A list of earlier major versions the module provides types for can also optionally be given after the
PAST_MAJOR_VERSIONS
keyword (see below). See
识别模块
for further in-depth discussion of the module URI and version numbering.
A list of additional major versions the module provides may be given using the
PAST_MAJOR_VERSIONS
keyword. For each of those versions and each QML file without a
QT_QML_SOURCE_VERSIONS
setting an additional entry in the
qmldir
file will be generated to specify the extra version. Furthermore, the generated module registration code will register the past major versions using
qmlRegisterModule
() on the C++ side. The module registration code is automatically generated for your QML module, unless you specify
NO_GENERATE_QMLTYPES
(but use of this option is strongly discouraged). Usage of
PAST_MAJOR_VERSIONS
adds some overhead when your module is imported. You should increment the major version of your module as rarely as possible. Once you can rely on all QML files importing this module to omit the version in their imports, you can safely omit
PAST_MAJOR_VERSIONS
. All the QML files will then import the latest version of your module. If you have to support versioned imports, consider supporting only a limited number of past major versions.
RESOURCE_PREFIX
is intended to encapsulate a namespace for the project and will often be the same for all QML modules that the project defines. It should be chosen to avoid clashing with the resource prefix of anything else used by the project or likely to be used by any other project that might consume it. A good choice is to incorporate the domain name of the organization the project belongs to. A common convention is to append
/imports
to the domain name to form the resource prefix. For example:
qt_add_qml_module(someTarget RESOURCE_PREFIX /my.company.com/imports ... )
When various files are added to the compiled-in resources, they are placed under a path formed by concatenating the
RESOURCE_PREFIX
and the target path. For the special case where the backing target is an executable, it may be desirable to place the module's
.qml
files and other resources directly under the
RESOURCE_PREFIX
instead. This can be achieved by specifying the
NO_RESOURCE_TARGET_PATH
option, which may only be used if the backing target is an executable.
OUTPUT_DIRECTORY
specifies where the plugin library,
qmldir
and typeinfo files are generated. When this keyword is not given, the default value will be the target path (formed from the
URI
) appended to the value of the
QT_QML_OUTPUT_DIRECTORY
variable. If that variable is not defined, the default depends on the type of backing target. For executables, the value will be the target path appended to
${CMAKE_CURRENT_BINARY_DIR}
, whereas for other targets it will be just
${CMAKE_CURRENT_BINARY_DIR}
. When the structure of the source tree matches the structure of QML module target paths (which is highly recommended),
QT_QML_OUTPUT_DIRECTORY
often isn't needed. The need for specifying the
OUTPUT_DIRECTORY
keyword should be rare, but if it is used, it is likely that the caller will also need to add to the
IMPORT_PATH
to ensure that
linting
,
cached compilation
of qml sources and
automatic importing
of plugins in static builds all work correctly.
默认情况下,
qt_add_qml_module()
will auto-generate a
.cpp
file that implements the plugin class named by the
CLASS_NAME
argument. The generated
.cpp
file will be automatically added to the plugin target as a source file to be compiled. If the project wants to provide its own implementation of the plugin class, the
NO_GENERATE_PLUGIN_SOURCE
option should be given. Where no
CLASS_NAME
is provided, it defaults to the
URI
with dots replaced by underscores, then
Plugin
appended. Unless the QML module has no plugin, the class name will be recorded as a
classname
line in the generated
qmldir
文件。
若
NO_PLUGIN_OPTIONAL
keyword is given, then the plugin is recorded in the generated
qmldir
file as non-optional. If all of a QML module's functionality is implemented in its backing target and the plugin target is separate, then the plugin can be optional, which is the default and recommended arrangement. The auto-generated plugin source file satisfies this requirement. Where a project provides its own
.cpp
implementation for the plugin, that would normally mean the
NO_PLUGIN_OPTIONAL
keyword is also needed because the plugin will almost certainly contain functionality that the QML module requires.
Type registration is automatically performed for the backing target's C++ sources that are processed by AUTOMOC. This will generate a typeinfo file in the
output directory
, the file name being the
target
name with
.qmltypes
appended. This file name can be changed using the
TYPEINFO
option if desired, but this should not normally be necessary. The file name is also recorded as a
typeinfo
entry in the generated
qmldir
file. Automatic type registration can be disabled using the
NO_GENERATE_QMLTYPES
option, in which case no typeinfo file will be generated, but the project will still be expected to generate a typeinfo file and place it in the same directory as the generated
qmldir
文件。
IMPORTS
provides a list of other QML modules that this module imports. Each module listed here will be added as an
import
entry in the generated
qmldir
file. If a QML file imports the this module, it also imports all the modules listed under
IMPORTS
. Optionally, a version can be specified by appending it after a slash, such as
QtQuick/2.0
. Omitting the version will cause the greatest version available to be imported. You may only specify the major version, as in
QtQuick/2
. In that case the greatest minor version available with the given major version will be imported. Finally,
auto
may be given as version (
QtQuick/auto
)。若
auto
is given, the version that the current module is being imported with is propagated to the module to be imported. Given an entry
QtQuick/auto
in a module
YourModule
, if a QML file specifies
import YourModule 3.14
, this results in importing version
3.14
of
QtQuick
. For related modules that follow a common versioning scheme, you should use
auto
.
OPTIONAL_IMPORTS
provides a list of other QML modules that this module
may
import at run-time. These are not automatically imported by the QML engine when importing the current module, but rather serve as hints to tools like
qmllint
. Versions can be specified in the same way as for
IMPORTS
. Each module listed here will be added as an
optional import
entry in the generated
qmldir
文件。
DEPENDENCIES
provides a list of other QML modules that this module depends on, but doesn't necessarily import. It would typically be used for dependencies that only exist at the C++ level, such as a module registering a class to QML which is a subclass of one defined in another module. The module version of the dependencies must be specified along with the module name, in the same form as used for
IMPORTS
and
OPTIONAL_IMPORTS
. Each module listed here will be added as a
depends
entry in the generated
qmldir
文件。
IMPORT_PATH
can be used to add to the search paths where other QML modules that this one depends on can be found. The other modules must have their
qmldir
file under their own target path below one of the search paths.
SOURCES
specifies a list of non-QML sources to be added to the backing target. It is provided as a convenience and is equivalent to adding the sources to the backing target with the built-in
target_sources()
CMake command.
QML_FILES
lists the
.qml
,
.js
and
.mjs
files for the module. These will be automatically
compiled into bytecode
and embedded in the backing target unless the
NO_CACHEGEN
option is given. The uncompiled file is always stored in the embedded resources of the backing target, even if
NO_CACHEGEN
is specified. Unless the
NO_LINT
option is given, the uncompiled files will also be
processed by
qmllint
via a separate custom build target. The files will also be used to populate type information in the generated
qmldir
file. See
qt_target_qml_sources()
for further details on the source file properties that can be set on these files or if files need to be added to the backing target after this command has been called.
RESOURCES
lists any other files needed by the module, such as images referenced from the QML code. These files will be added as compiled-in resources (see
RESOURCE_PREFIX
for an explanation of the base point they will be located under). If needed, their relative location can be controlled by setting the
QT_RESOURCE_ALIAS
source property, just as for
.qml
files (see
缓存编译的 QML 源
).
NO_GENERATE_QMLDIR
can be given to disable the automatic generation of the
qmldir
file. This should normally be avoided, but for cases where the project needs to provide its own
qmldir
file, this option can be used.
If the backing target is a static library and that static library will be installed,
OUTPUT_TARGETS
should be given to provide a variable in which to store a list of additional targets that will also need to be installed. These additional targets are generated internally by
qt_add_qml_module()
and are referenced by the backing target's linking requirements as part of ensuring that resources are set up and loaded correctly.
DESIGNER_SUPPORTED
keyword should be given if the QML module supports Qt Quick Designer. When present, the generated
qmldir
file will contain a
designersupported
line. See
Module Definition qmldir Files
for how this affects the way Qt Quick Designer handles the plugin.