The example below demonstrates how to create a library which exposes C++ to QML. The directory structure for the example looks like this:
├── CMakeLists.txt └── example └── mylib ├── CMakeLists.txt ├── mytype.cpp ├── mytype.h
The toplevel
CMakeLists.txt
file does some basic setup using
qt_standard_project_setup
, and then uses
add_subdirectory
to include the one in mylib:
cmake_minimum_required(VERSION 3.16) project(qmlmodule VERSION 1.0.0 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(Qt6 REQUIRED COMPONENTS Qml) qt_standard_project_setup(REQUIRES 6.5) add_subdirectory(example/mylib)
The subdirectories are structured to correspond to the QML module’s URI, but with the dots replaced by slashes. That’s the same logic the engine uses when it searches for a module in the import paths . Following this subdirectory structure helps tooling.
mytype.h
declares a class and uses the
declarative registration macros
to expose it to the engine.
In the subdirectory’s
CMakeLists.txt
we call
qt_add_qml_module
. Compared to
构建 QML 应用程序
, the invocation is slightly different:
qt_add_qml_module(mylib URI example.mylib VERSION 1.0 SOURCES mytype.h mytype.cpp QML_FILES MyQmlType.qml )
The target for
mylib
has not been created before. When the target passed to
qt6_add_qml_module
does not exist, it automatically creates a library target. This avoids a separate call to
qt_add_library
. To register QML types defined in C++, add their header and source files as arguments to the SOURCES parameter.
When the project is built, in addition to the library, a QML plugin is also built. The plugin's auto-generated class extends from
QQmlEngineExtensionPlugin
. The mylib library itself already contains the code to register the types with the engine. However, that is only useful in cases where we can link against the library. To make the module usable in a QML file loaded by
qml
,
QML Runtime Tool
, a plugin is needed that can be loaded. The plugin is then responsible for actually linking against the library, and ensuring that the types get registered.
Note that the automatic plugin generation is only possible if the module does not do anything besides registering the types. If it needs to do something more advanced like registering an image provider in
initializeEngine
, you still need to manually write the plugin.
qt6_add_qml_module
has support for this with
NO_GENERATE_PLUGIN_SOURCE
.
Also, following the directory layout convention helps tooling. That layout is mirrored in the build directory. Which means that you can pass the path to your build directory to the QML tool (via the
-I
flag), and it will find the plugin.