Ich bin verwirrt über Module in Qt QML. Ich habe alle Dokumente gelesen, aber einige grundlegende Ideen sind nicht klar.
Ich verstehe, dass ich eine Reihe von QML-Dateien in ein Verzeichnis einfügen und eine qmldir-Datei hinzufügen kann, um ein identifiziertes Modul zu beschreiben. Wenn ich dies mache und den QML_IMPORT_PATH anpasse, ist QtCreator glücklich und hört auf, die Import ModuleName 1.0-Zeile zu unterstreichen.
Der Schöpfer ist also glücklich, aber es funktioniert nicht. Ich bekomme das Modul nicht installiert .. Meine Fragen sind:
Entschuldigung, für all diese Fragen, aber die Grundlagen dieser Module sind einfach nicht klar. Ich verstehe nicht, ob ein "Modul" nur das Teilen von Dateien ist oder eine kompilierte Einheit ist.
danke für jede hilfe.
Ich werde versuchen, deine Fragen zu beantworten:
engine->addImportPath()
hinzugefügt haben.Es gibt eine Reihe von Dingen, die dazu führen können, dass ein Modul nicht geladen wird. Sie können Folgendes überprüfen:
module TestModule
in qmldir hat, muss der Name der Moduledirectory TestModule
sein.QML2_IMPORT_PATH
(stellen Sie sicher, dass sich 2
im Namen befindet) env-Variable, um auf das Verzeichnis zu verweisen, das Ihr Modul enthält. Es gibt auch eine QQmlEngine::addImportPath
-Methode, die das Verzeichnis der Liste hinzufügt, um nach Plugins zu suchen.ldd
unter Linux überprüfen.QT_PLUGIN_PATH
kann beim Laden von Plugins hilfreich sein. Es sollte auf ein Verzeichnis verweisen, das das Verzeichnis Ihres Plugins enthält, nicht das Verzeichnis des Plugins.QT_DEBUG_PLUGINS=1
und QML_IMPORT_TRACE=1
Sie können diesen Link auch lesen: https://doc.qt.io/qt-5/qtqml-modules-identifiedmodules.html
In meinem Fall (ich habe alle QML-Dateien in qrc-Ressourcen) wurde daran gearbeitet, qmldir zu Ressourcen hinzuzufügen und die Methode addImportPath ("qrc: /") von QQmlApplicationEngine aufzurufen.
Meine main.cpp sieht so aus:
QQmlApplicationEngine engine;
engine.addImportPath("qrc:/");
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
Wichtige Teile meiner .pro-Datei sehen folgendermaßen aus:
RESOURCES += qml.qrc \
MyModule/mymodule.qrc
QML_IMPORT_PATH += $$PWD
Mein qmldir:
module MyModule
MyItem 2.0 MyItem20.qml
MyItem 2.1 MyItem21.qml
Mein qrc:
<RCC>
<qresource prefix="/MyModule">
<file>MyItem20.qml</file>
<file>MyItem21.qml</file>
<file>qmldir</file>
</qresource>
</RCC>
Und zum Schluss noch meine main.qml:
import QtQuick 2.5
import QtQuick.Window 2.2
import MyModule 2.0
Window {
visible: true
width: 640
height: 480
MyItem {
anchors.fill: parent
}
}
QtCreator ist glücklich (unterstreicht nicht Komponenten und Importe) und das Modul wird geladen . Hoffe, das hilft.
Ich möchte auf arxarian's answer eingehen, was meiner Meinung nach die beste Technik für die Integration von Modulen ist. Ich konnte diese Gedanken jedoch nicht in einen Kommentar einfügen. Hier ist eine neue Antwort.
Es ist wichtig zu verstehen, dass es sich bei qml-Modulen und ihren zugehörigen Ressourcen um Laufzeitentitäten handelt und dass sie an einem bestimmten Ort relativ zu der ausführbaren Datei vorhanden sind, sofern sie nicht in den Anwendungsressourcen enthalten sind. Indem sie in die Ressourcen aufgenommen werden, sind sie immer noch Laufzeitentitäten, sie befinden sich jedoch unter dem Pfad qrc:/root innerhalb der Anwendungsbinärdatei. Dieses Verstecken der Module ist der Hauptgrund, warum ich denke, dass dies die beste Technik ist, es sei denn, Sie möchten, dass Ihre Module nach der Bereitstellung für die Revision geöffnet werden können oder unabhängig als vorkompilierte Plugins (dh im Ressourcenspeicher eines dynamisch verknüpften Systems) bereitgestellt werden können Bibliothek).
Hier also meine Erklärung der wichtigen Elemente von arxarian's answer :
engine.addImportPath("qrc:/");
ist vor dem Laden von qml im C++ - Code erforderlich, um die Engine anzuweisen, im Anwendungsressourcenspeicher nach qml-Modulen zu suchen.RESOURCES += MyModule/mymodule.qrc
wird in der Projektdatei (.pro) benötigt, um die Moduldateien zum Anwendungsressourcenspeicher hinzuzufügen.QML_IMPORT_PATH += $$PWD
in der Projektdatei weist Qt Creator an, nach dem Modul zu suchen, das vom Stamm des Projektquellbaums aus beginnt. In meinem Fall musste ich dies auf ein Unterverzeichnis (z. B. "ui/modules") setzen, da meine Modulverzeichnisse dort begannen. Der Importpfad sollte die Wurzeln unter allen Modulverzeichnissen enthalten. Soweit ich das beurteilen kann, ist diese Anweisung nur für den Qt Creator IDE bestimmt und wirkt sich nicht auf den Build aus - deshalb ist # 1 erforderlich.<qresource prefix="/MyModule">
in der .qrc-Datei des Moduls definiert das Unterverzeichnis des Moduls relativ zu qrc:/root im Ressourcenspeicher der Anwendung.import MyModule <version>
-Anweisung in qml ist jetzt für den Erfolg eingerichtet. Beim Start hat die Engine das Modul in seinem Verzeichnis unter qrc:/gefunden, die qmldir-Datei dort analysiert, um das Modul zu definieren, und den Namen und die Version aus diesen Einträgen festgelegt.Hoffentlich hilft das anderen, zu verstehen, was los ist, und bitte lasst es mich wissen, wenn ich etwas missverstanden habe.
Ein ähnliches Problem hat mich ein bisschen Zeit gekostet, also poste ich es hier, um dem nächsten Mann vielleicht etwas Mühe zu ersparen.
Mein Problem war, dass sich ein unsichtbarer Charakter in den Modulnamen eingeschlichen hatte. Wahrscheinlich durch Kopieren und Einfügen. Hier meine Ausgabe:
Beispielfehlerausgabe:
MyEngine failed to load component
qrc:/qml/main.qml:53 Type MyComponent unavailable
file:///Users/<pathToProject>/MyProject/qml/MyModule/MyComponent.qml:-1 No such file or directory
Alles sieht gut aus und der angezeigte Pfad ist tatsächlich der richtige. Also was ist los?
Kopieren Sie nun diesen Pfad in ein Terminalfenster:
file:///Users/<pathToProject>/MyProject/qml/MyModule/<feff>MyComponent.qml
Da ist es, das:
"<feff>"
Das Problem wurde gelöst, indem der Komponentenname in der qmldir-Datei manuell neu eingegeben wurde und somit das unsichtbare Zeichen effektiv gelöscht wurde.