Auf dieser Seite

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.h

Diese 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.