web-dev-qa-db-fra.com

Le module Qt5 QML n'est pas installé

Je suis confus à propos des modules dans Qt QML. J'ai lu tous les documents, mais cela ne précise pas certaines idées de base.

Je comprends que je peux mettre un tas de fichiers QML dans un répertoire et ajouter un fichier qmldir pour décrire un module identifié. Quand je fais cela et que j'ajuste QML_IMPORT_PATH, QtCreator est content et arrête de souligner la ligne d'importation ModuleName 1.0.

Donc, le créateur est heureux, mais cela ne fonctionne pas. Je reçois le module n'est pas installé . Mes questions sont:

  • qu'est-ce que cela signifie par "installé". J'ai un répertoire de fichiers, mais je ne les ai "installés" nulle part.
  • devrais-je construire/compiler le module pour créer une DLL/.so?
  • les fichiers du module QML vont-ils dans les ressources de l’application principale, sinon ils se trouvent où?
  • mon fichier main.qml fait partie des ressources de l'application, comment l'application localise-t-elle les ressources du module au moment de l'exécution.

Désolé, pour toutes ces questions, mais les bases de ces modules ne sont tout simplement pas claires. Je ne comprends pas si un "module" est simplement le partage de fichiers ou s'il s'agit d'une unité compilée.

merci pour toute aide.

12
jkj yuio

Je vais essayer de répondre à vos questions:

  • Je pense que installed signifie qu’ils sont situés dans les chemins appropriés, donc
    qu'ils peuvent être trouvés à l'exécution
  • Vous ne devez pas nécessairement créer/construire un QmlExtrensionPlugin à cette fin. Vous pouvez également utiliser comme module des fichiers QML simples dans un seul directory avec un qmldir décrivant ce module. C'est la question de Distribuer votre code - avec QmlExtensionPlugin, vous fournissez le module Compilé, si vous voulez masquer le code.
  • Les modules peuvent être dans le système de ressources ou sous forme de fichiers sur disque, à vous de choisir.
  • L'application recherche les modules dans des chemins prédéfinis - dans le répertoire de votre application, dans le chemin des plugins QT, dans QML2_IMPORT_PATH, dans les répertoires que vous avez ajoutés à l'aide de engine->addImportPath().

Il y a beaucoup de choses qui peuvent empêcher le chargement d'un module. Vous pouvez vérifier les éléments suivants:

  1. L'identificateur de module dans qmldir doit être identique à l'annuairenom, où réside réellement le module. Par exemple, si votre module A l'identifiant de module module TestModule dans qmldir, votre nom de modulesdirectory doit être TestModule.
  2. S'il s'agit d'une extension QML Plugin (bibliothèque partagée), assurez-vous que le nom de répertoire de ce plugin est Identique au nom du plugin.
  3. export QML2_IMPORT_PATH (assurez-vous que le nom contient 2) variable env pour pointer vers le répertoire contenant votre module. Il existe également une méthode QQmlEngine::addImportPath, qui ajoute le répertoire à la liste pour rechercher des plugins.
  4. S'il s'agit d'un plugin d'extension qml (bibliothèque partagée), il se peut qu'il manque des dépendances. Vous pouvez le vérifier par Dependency Walker sous Windows ou par la commande ldd sous Linux.
  5. La définition de la variable d'exécution QT_PLUGIN_PATH peut aider à charger les plugins. Il devrait pointer sur un répertoire contenant le répertoire de votre plugin, pas sur le répertoire du plugin lui-même.
  6. Vous pouvez également activer les traces pour voir ce qui se passe pendant le chargement des plugins pour une meilleure compréhension du problème - variables d'environnement d'exportation QT_DEBUG_PLUGINS=1 et QML_IMPORT_TRACE=1

Vous pouvez également lire ce lien: https://doc.qt.io/qt-5/qtqml-modules-identifiedmodules.html

9
rightaway717

Dans mon cas (j'ai tous les fichiers QML dans les ressources qrc), j'ai également ajouté qmldir aux ressources et appelé la méthode addImportPath ("qrc: /") de QQmlApplicationEngine.

Mon main.cpp ressemble à:

QQmlApplicationEngine engine;
engine.addImportPath("qrc:/");
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

Les parties importantes de mon fichier .pro ressemblent à:

RESOURCES += qml.qrc \
    MyModule/mymodule.qrc

QML_IMPORT_PATH += $$PWD

Mon qmldir:

module MyModule

MyItem          2.0 MyItem20.qml
MyItem          2.1 MyItem21.qml

Mon qrc:

<RCC>
    <qresource prefix="/MyModule">
        <file>MyItem20.qml</file>
        <file>MyItem21.qml</file>
        <file>qmldir</file>
    </qresource>
</RCC>

Et enfin mon 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 est heureux (ne souligne pas les composants et les importations) et le module est chargé . J'espère que cela vous aidera.

8
arxarian

Je souhaite développer/ la réponse d'arxarian - qui, je pense, est la meilleure technique pour intégrer des modules - mais ne peut pas intégrer ces idées dans un commentaire. Voici donc une nouvelle réponse.

Il est important de commencer par comprendre que les modules qml et leurs ressources associées sont des entités d'exécution et sont supposés exister séparément à un emplacement donné par rapport à l'exécutable, à moins qu'ils ne soient inclus dans les ressources de l'application. En les incluant dans les ressources, ce sont toujours des entités d'exécution, mais elles existent sous le chemin d'accès qrc:/root dans le binaire de l'application. Cacher les modules est la raison principale pour laquelle j'estime qu'il s'agit de la meilleure technique, sauf si vous souhaitez que vos modules soient ouverts à la révision après le déploiement ou qu'ils puissent être déployés indépendamment en tant que plugins précompilés (c'est-à-dire, dans le stockage de ressources d'un serveur lié dynamiquement). bibliothèque).

Alors, voici mon explication des éléments importants de la réponse d'Arxarian :

  1. engine.addImportPath("qrc:/"); est nécessaire dans le code C++ avant de charger le qml pour indiquer au moteur de rechercher des modules qml dans le stockage des ressources de l'application.
  2. RESOURCES += MyModule/mymodule.qrc est nécessaire dans le fichier de projet (.pro) pour ajouter les fichiers du module au application resource storage .
  3. QML_IMPORT_PATH += $$PWD dans le fichier de projet indique à Qt Creator de rechercher le module à partir de la racine de l'arborescence des sources du projet. Dans mon cas, je devais définir ceci dans un sous-répertoire (par exemple, "ui/modules") car mes répertoires de modules avaient commencé à cet endroit. Le chemin d'importation doit inclure la ou les racine (s) sous tous les répertoires de module. Autant que je sache, cette instruction ne concerne que Qt Creator IDE et n'a pas d'incidence sur la construction - c'est pourquoi # 1 est nécessaire.
  4. Le contenu du fichier qmldir est tel quel standard pour tous les modules qml , mais son inclusion dans le fichier de ressources .qrc du module n'est intuitive que lorsque vous réfléchissez à ce qui se passe avec le stockage à l'exécution. Il doit être dans le fichier .qrc pour pouvoir être inclus dans le stockage des ressources de l'application afin que le moteur puisse le trouver au moment de l'exécution pour définir le module. <qresource prefix="/MyModule"> dans le fichier .qrc du module définit le sous-répertoire du module par rapport à qrc:/root dans le stockage des ressources de l'application.
  5. L'instruction import MyModule <version> dans qml est maintenant configurée pour réussir. Au démarrage, le moteur aura localisé le module dans son répertoire sous qrc: /, analysé le fichier qmldir afin de définir le module et établi le nom et la version à partir de ces entrées.

J'espère que cela aidera les autres à comprendre ce qui se passe, et s'il vous plaît laissez-moi savoir si j'ai mal compris quelque chose.

3
Travis R

Un problème similaire m'a coûté un peu de temps, je l'ai donc posté ici pour peut-être sauver l'effort d'un autre gars.

Mon problème était qu'un personnage invisible s'était introduit dans le nom du module. Probablement par copier/coller. Voici mon numéro:

Exemple d'erreur de sortie:

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

Tout semble aller bien et le chemin affiché est en effet le bon. Alors qu'est-ce qui ne va pas?

Maintenant, copiez ce chemin dans une fenêtre de terminal:

file:///Users/<pathToProject>/MyProject/qml/MyModule/<feff>MyComponent.qml

Le voici:

"<feff>"

Le problème a été résolu en retapant manuellement le nom du composant dans le fichier qmldir, supprimant ainsi le caractère invisible.

0
Tony