QML modules have become more powerful and easier to use in Qt 6. The following sections describe how to port QML modules to the qt_add_qml_module CMake API.
另请参阅 Modern QML modules on how to modernize a QML module that already uses qt_add_qml_module .
使用 qmllint to support you through the process.
Each QML module defined with
qt_add_qml_module
拥有
_qmllint
CMake target that you can use to identify potential issues or improvements. For a QML module called
MyQmlLibrary
使用
MyQmlLibrary_qmllint
, for example. To run
qmllint
on all QML modules, use
all_qmllint
.
The warning categories of qmllint that hint at QML module issues are:
To make
qt_add_qml_module
available in CMake, add
Core
and
Qml
to your
find_package
call in the project's top-level
CMakeLists.txt
文件:
find_package(Qt6 REQUIRED COMPONENTS Core Qml)
qt_standard_project_setup sets up Qt CMake 策略 needed for qt_add_qml_module , among other things.
调用
qt_standard_project_setup
in the project's top-level
CMakeLists.txt
file before any
qt_add_qml_module
call:
qt_standard_project_setup(REQUIRES 6.8)
qt_add_qml_module
is the CMake function that takes care of generating QML modules. It automatically generates
qmldir
and
qmltypes
files, and sets up tooling like
qmlcachegen
or
qmllint
.
QML modules can be added to both executable and library targets in CMake. QML modules attached to the executable target can't be used or linked by other executables, while QML modules attached to library targets can.
In this case, the source files of the QML module are treated as part of the executable itself, rather than being compiled into a separate library. This means neither a module nor plugin library for this module is created—–the module is fully integrated into the executable. As a result, the module is tied to that specific program and cannot be reused by other executables or libraries.
To add a QML module to your executable, in your
CMakeLists.txt
:
# pre-existing:
qt_add_executable(MyApp main.cpp)
# add this
qt_add_qml_module(MyApp
URI MyAppModule
QML_FILES
Main.qml # and possibly more .qml files
)
The
Main.qml
should start with an upper case letter so that it can be instantiated by
loadFromModule
methods like
QQmlApplicationEngine::loadFromModule
or
QQmlComponent::loadFromModule
. Also, the QML module URI should be different from the target name to avoid name clashes in the build folder.
To add a QML module to your library, in your
CMakeLists.txt
:
qt_add_qml_module(MyQmlLibrary
URI MyQmlModule
QML_FILES MyQmlComponent1.qml MyQmlComponent2.qml...
SOURCES MyCppComponent1.h MyCppComponent1.cpp MyCppComponent2.h MyCppComponent2.cpp...
RESOURCES MyResource1.png MyResource2.png...
)
qt_add_qml_module
创建
SHARED
library via
qt_add_library
若
MyQmlLibrary
target does not exist yet, like in this example.
注意: Your QML module URI should be different from the target name to avoid name clashes in the build folder.
使用
loadFromModule
to load your QML file, for example:
engine.load(QUrl(QStringLiteral("qrc:/MyQmlModule/Main.qml")));
// becomes
engine.loadFromModule("MyQmlModule", "Main");
qt_add_qml_module
automatically generates
qmldir
files. If you have singletons in your
qmldir
, declare them in your
CMakeLists.txt
先于
qt_add_qml_module
call with:
set_source_files_properties(MySingleton.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE)
Delete the handwritten
qmldir
after that.
qt_add_qml_module
auto-generates
qmltypes
files when all your types are using
declarative type registration
, which removes the need to generate
qmltypes
files by hand using tools like
qmlplugindump
.
To achieve that, remove manual calls to
qmlRegisterType
and its variants. Then,
register your types declaratively
by using
QML_ELEMENT
,例如:
// add this header
#include <QtQml/qqmlregistrations.h>
class MyComponent: public QObject {
Q_OBJECT
// add this line to register MyComponent as 'MyComponent' in QML.
QML_ELEMENT
....
};
见 Registering C++ Types with the QML Type System on how to handle more complicated registration cases like foreign type registration.
Delete the handwritten
qmltypes
files after that.
qt_add_qml_module can generate a QML module plugin automatically for you. You don't need a handwritten plugin if your plugin's only task is to do type registration. Remove the plugin altogether if switching to declarative type registration did remove all the code from your plugin.
Make sure that you
remove
the
NO_PLUGIN
,
NO_PLUGIN_OPTIONAL
,
NO_CREATE_PLUGIN_TARGET
,和
NO_GENERATE_PLUGIN_SOURCE
arguments from
qt_add_qml_module
to allow automatic plugin generation.
qt_add_qml_module
automatically generates
qrc
files. To list resources in the
qrc
files, like images or sound files, add them to
qt_add_qml_module
's
RESOURCES
argument. You can find the Module's resources under
:/qt/qml/MyQmlLibraryModule/
.
Replace directory imports with QML module imports. For example,
import "content" // contains SomeType.qml
// becomes
import MyQmlModule // contains SomeType.qml
SomeType {
...
}
Note that files inside a QML module automatically import their own QML module. You can remove the self-imports.
另请参阅 Changes to Qt QML and Modern QML modules .