Alles mit CMake zusammenführen
Der CMake-Befehl `qt_add_qml_module` ist die empfohlene Methode zum Definieren von QML-Modulen. Er automatisiert die Typregistrierung, die Einbettung von Ressourcen, die Erstellung von Plugins und die Integration von Werkzeugen. Auf dieser Seite werden die Konzepte hinter ` qt_add_qml_module ` erläutert und gängige Anwendungsmuster vorgestellt.
Eine vollständige Übersicht über alle Optionen finden Sie unter „qt_add_qml_module“.
Wichtige Konzepte
Bevor wir uns Beispiele ansehen, ist es hilfreich zu verstehen, was „ qt_add_qml_module “ tatsächlich erstellt:
- Ein Backing-Target – eine Bibliothek (oder ein ausführbares Programm), die den C++-Code des Moduls, kompilierte QML-Dateien und Ressourcen enthält. Dies ist das erste Argument von `
qt_add_qml_module` und das Target, gegen das Sie verknüpfen. Es kann sich entweder um ein bestehendes Target handeln (das zuvor mit `qt_add_executable` oder `qt_add_library` erstellt wurde) oder `qt_add_qml_module` erstellt es für Sie. - Ein Plugin-Ziel – eine kleine Bibliothek, die es der QML-Engine ermöglicht, das Modul zur Laufzeit dynamisch zu laden. Es wird automatisch erstellt und ist vom Backing-Ziel getrennt. Wenn eine ausführbare Datei direkt mit dem Backing-Ziel verknüpft wird, wird das Plugin zur Laufzeit nicht geladen. Das Plugin kann mithilfe von NO_PLUGIN vollständig weggelassen werden.
- Eine qmldir-Datei – eine Metadatendatei des Moduls, die der QML-Engine mitteilt, welche Typen das Modul bereitstellt und wo diese zu finden sind. Sie wird automatisch generiert.
- Eine „typeinfo“-Datei (
.qmltypes) – maschinenlesbare Typinformationen, die von QML-Tools (qmlcachegen, qmllint, qmlls, Qt Creator) verwendet werden. Wird ebenfalls automatisch generiert.
Verzeichnisstruktur
Die Struktur des Quellverzeichnisses sollte die URI des Moduls widerspiegeln. Die URI wird in einen Pfad umgewandelt, indem Punkte durch Schrägstriche ersetzt werden. Ein Modul mit der URI MyCompany.Controls sollte sich beispielsweise unter folgendem Pfad befinden:
src/MyCompany/Controls/CMakeLists.txt
src/MyCompany/Controls/Button.qml
src/MyCompany/Controls/mywidget.cpp
src/MyCompany/Controls/mywidget.hDiese Konvention ermöglicht es der QML-Engine und den Tools, Module ohne zusätzliche Konfiguration zu finden. Wenn Ihre Verzeichnisstruktur nicht mit der URI übereinstimmt, müssen Sie OUTPUT_DIRECTORY so festlegen, dass die Build-Ergebnisse in einem Pfad abgelegt werden, der der URI entspricht, sowie IMPORT_PATH, damit die QML-Engine und die Tools das Modul finden können.
Häufige Muster
Reine QML-Anwendung
Der einfachste Fall: eine ausführbare Datei, die ausschließlich QML-Dateien und keine C++-Typen enthält.
cmake_minimum_required(VERSION 3.16)
project(myapp LANGUAGES CXX)
find_package(Qt6 REQUIRED COMPONENTS Quick)
qt_standard_project_setup(REQUIRES 6.8)
qt_add_executable(myapp)
qt_add_qml_module(myapp
URI MyApp
QML_FILES
Main.qml
Button.qml
RESOURCES
images/logo.png
)
target_link_libraries(myapp PRIVATE Qt6::Quick)Da das zugrunde liegende Ziel eine ausführbare Datei ist, wird kein Plugin erstellt. Die QML-Dateien werden kompiliert und als Ressourcen eingebettet. Das Schlüsselwort „ RESOURCES “ fügt Nicht-QML-Dateien (Bilder, Schriftarten usw.) derselben Ressourcenhierarchie hinzu.
Anwendung mit C++-Typen
Eine Anwendung, die C++-Typen für QML verfügbar macht:
qt_add_executable(myapp)
qt_add_qml_module(myapp
URI MyApp
QML_FILES
Main.qml
SOURCES
backend.cpp backend.h
)Die C++-Typen in „ backend.h “ müssen mit „ QML_ELEMENT “ (oder ähnlichen Makros wie „ QML_NAMED_ELEMENT “) annotiert werden und das Makro „ Q_OBJECT “ oder „ Q_GADGET “ verwenden. Die Typregistrierung erfolgt automatisch über „ AUTOMOC “. Eine vollständige Übersicht über die verfügbaren Registrierungsmakros finden Sie unter „Registrierung von C++-Typen im QML-Typsystem “.
Wiederverwendbares Bibliotheksmodul
Ein als Bibliothek gepacktes QML-Modul, das von anderen Projekten oder Modulen importiert werden kann:
# In src/MyCompany/Controls/CMakeLists.txt
qt_add_qml_module(mycontrols
URI MyCompany.Controls
QML_FILES
Button.qml
Slider.qml
SOURCES
theme.cpp theme.h
)Dadurch werden zwei Ziele erstellt: „ mycontrols “ (die zugrunde liegende Bibliothek) und „ mycontrolsplugin “ (das Plugin). Andere Module importieren es mit „ import MyCompany.Controls “ in QML. Anwendungen, die direkt mit „ mycontrols “ verknüpft sind, müssen das Plugin zur Laufzeit nicht laden.
Anwendung mit einem Bibliotheksmodul
Verwendung des Moduls „ mycontrols “ aus dem obigen Beispiel „Reusable Library Module “:
# In the application's CMakeLists.txt
qt_add_executable(myapp)
qt_add_qml_module(myapp
URI MyApp
QML_FILES Main.qml
DEPENDENCIES TARGET mycontrols
)
target_link_libraries(myapp PRIVATE mycontrols)Die Zeile „DEPENDENCIES“ stellt sicher, dass die QML-Tools (qmlcachegen, qmllint, qmlls) die von MyCompany.Controls bereitgestellten Typen finden können.
// In Main.qml
import MyCompany.Controls
Button { text: "Click me" }Modul mit Singletons
QML-Dateien, die Singleton-Typen bereitstellen, benötigen eine Quelldatei-Eigenschaft, die vor dem Aufruf von ` qt_add_qml_module ` festgelegt werden muss:
set_source_files_properties(Theme.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE)
qt_add_qml_module(mymodule
URI MyModule
QML_FILES
Theme.qml
Main.qml
)Die QML-Datei muss außerdem „ pragma Singleton “ enthalten. Sowohl die CMake-Eigenschaft als auch das QML-Pragma sind erforderlich.
Modul mit benutzerdefiniertem Plugin
Wenn Sie eine benutzerdefinierte Initialisierung durchführen müssen (z. B. die Registrierung eines Bildanbieters), können Sie eine eigene Unterklasse von ` QQmlEngineExtensionPlugin ` bereitstellen.
# In CMakeLists.txt
qt_add_qml_module(mymodule
URI MyModule
NO_GENERATE_PLUGIN_SOURCE
NO_PLUGIN_OPTIONAL
CLASS_NAME MyModulePlugin
QML_FILES
Main.qml
SOURCES
myimageprovider.cpp myimageprovider.h
)
# Add the custom plugin source to the plugin target
target_sources(mymoduleplugin PRIVATE plugin.cpp)// In plugin.cpp
#include <QtQml/QQmlEngineExtensionPlugin>
#include "myimageprovider.h"
class MyModulePlugin : public QQmlEngineExtensionPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
public:
void initializeEngine(QQmlEngine *engine, const char *uri) override
{
engine->addImageProvider("myprovider", new MyImageProvider);
}
};
#include "plugin.moc"NO_GENERATE_PLUGIN_SOURCE weist das Build-System an, die Standard-Plugin-Quelldatei nicht zu generieren. CLASS_NAME muss mit dem Klassennamen in Ihrer Implementierung übereinstimmen. NO_PLUGIN_OPTIONAL stellt sicher, dass das Plugin immer geladen wird, da es Initialisierungslogik enthält, die andernfalls übersprungen würde.
Hinzufügen weiterer QML-Dateien
Für QML-Dateien, die nach dem ersten Aufruf von ` qt_add_qml_module ` hinzugefügt werden, verwenden Sie `qt_target_qml_sources`:
qt_target_qml_sources(my_qml_module
QML_FILES
DynamicallyAddedType.qml
)Dies ist nützlich, um Dateien je nach Plattform oder Konfiguration bedingt einzubinden.
Ausführliche CMake-Referenz
Ausführliche Informationen zu allen CMake-Befehlen, Eigenschaften, Variablen und Richtlinien finden Sie unter CMake-Integration für QML.
Siehe auch „QML-Module“, „qt_add_qml_module“ und „QML-Module schreiben“.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.