web-dev-qa-db-de.com

Qt5 QML-Modul ist nicht installiert

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:

  • was bedeutet es "installiert". Ich habe ein Verzeichnis von Dateien, aber ich habe sie nirgendwo "installiert".
  • sollte ich das Modul erstellen/kompilieren, um eine DLL/.so zu erstellen?
  • werden die QML-Dateien des Moduls in die Ressourcen der Haupt-App übernommen? Wo sind sie sonst zu finden?
  • meine main.qml-Datei ist Teil der App-Ressourcen. Wie ermittelt die App die Ressourcen des Moduls zur Laufzeit?.

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.

12
jkj yuio

Ich werde versuchen, deine Fragen zu beantworten:

  • Ich denke installiert bedeutet, dass sie sich in den richtigen Pfaden befinden
    dass sie zur Laufzeit gefunden werden können
  • Sie sollten zu diesem Zweck nicht unbedingt ein QmlExtrensionPlugin erstellen/erstellen. Sie können auch einfache QML-Dateien in einem Modul als Modul verwendenDirectory mit einem qmldir, das dieses Modul beschreibt. Es geht darum, Ihren Code zu verteilen - mit QmlExtensionPlugin geben Sie das Modul kompiliert an, wenn Sie den Code ausblenden möchten.
  • Die Module können im Ressourcensystem oder als Dateien auf der Festplatte sein, es liegt an Ihnen.
  • Die App sucht nach Modulen in vordefinierten Pfaden - im Verzeichnis Ihrer App, im Pfad der QT-Plugins, in QML2_IMPORT_PATH in Verzeichnissen, die Sie mit 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:

  1. Der Modulbezeichner in qmldir sollte mit dem Verzeichnis identisch sein, in dem sich das Modul tatsächlich befindet. Wenn beispielsweise Ihr Modul Die Modul-ID module TestModule in qmldir hat, muss der Name der Moduledirectory TestModule sein.
  2. Wenn es sich um eine QML-Erweiterung Plugin (gemeinsam genutzte Bibliothek) handelt, stellen Sie sicher, dass der Verzeichnisname des Plugins Dem Namen des Plugins entspricht.
  3. export 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.
  4. Wenn es sich um ein qml-Erweiterungs-Plugin (gemeinsam genutzte Bibliothek) handelt, fehlen möglicherweise Abhängigkeiten. Sie können dies mit dem Befehl Dependency Walker unter Windows oder dem Befehl ldd unter Linux überprüfen.
  5. Die Einstellung der Laufzeitvariable 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.
  6. Sie können auch Ablaufverfolgungen aktivieren, um zu sehen, was während des Ladens von Plugins vorgeht, um das Problem besser zu verstehen - exportieren Sie die Umgebungsvariablen 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

9
rightaway717

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.

8
arxarian

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 :

  1. engine.addImportPath("qrc:/"); ist vor dem Laden von qml im C++ - Code erforderlich, um die Engine anzuweisen, im Anwendungsressourcenspeicher nach qml-Modulen zu suchen.
  2. RESOURCES += MyModule/mymodule.qrc wird in der Projektdatei (.pro) benötigt, um die Moduldateien zum Anwendungsressourcenspeicher hinzuzufügen.
  3. 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.
  4. Der Inhalt der qmldir-Datei ist wie folgt: Standard für alle qml-Module . Die Aufnahme in die .qrc-Ressourcendatei des Moduls ist jedoch erst dann intuitiv, wenn Sie darüber nachdenken, was mit dem Laufzeitspeicher geschieht. Es muss in der .qrc-Datei enthalten sein, damit es in den Anwendungsressourcenspeicher aufgenommen wird, damit die Engine es zur Laufzeit finden kann, um das Modul zu definieren. <qresource prefix="/MyModule"> in der .qrc-Datei des Moduls definiert das Unterverzeichnis des Moduls relativ zu qrc:/root im Ressourcenspeicher der Anwendung.
  5. Die 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.

3
Travis R

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.

0
Tony