Qt5没有安装QML模块

jkj*_*uio 13 qt qml qt5

我对Qt QML中的模块感到困惑.我已经阅读了所有的文档,但它没有说明一些基本的想法.

我知道我可以将一堆QML文件放入一个目录中并添加一个qmldir文件来描述一个已识别的模块.当我这样做并调整QML_IMPORT_PATH时,QtCreator很高兴并停止强调导入ModuleName 1.0行.

所以创作者很高兴,但它不起作用.我没有安装模块.我的问题是:

  • "安装"是什么意思.我有文件目录,但我没有在任何地方"安装"它们.
  • 我应该构建/编译模块来制作DLL/.so吗?
  • 模块QML文件是否进入主应用程序的资源,否则它们在哪里可以找到?
  • 我的main.qml文件是应用程序资源的一部分,应用程序如何在运行时找到模块的资源.

对不起,对于所有这些问题,但这些模块的基础知识还不清楚.我不明白"模块"是仅仅是文件共享还是编译单元.

谢谢你的帮助.

rig*_*717 9

我会尽力回答你的问题:

  • 我认为安装意味着它们位于正确的路径中,因此
    可以在运行时找到它们
  • 您不一定要为此目的创建/构建QmlExtrensionPlugin.您还可以在一个目录中使用简单QML文件作为模块,并使用描述此模块的qmldir.这是分发代码的问题 - 如果要隐藏代码,可以使用QmlExtensionPlugin提供编译的模块.
  • 模块可以在资源系统中,也可以作为磁盘上的文件,由您自己决定.
  • 该应用程序在预定义路径中查找模块 - 在您的应用程序目录中,在QT插件路径中,在QML2_IMPORT_PATH中,在您添加的目录中 engine->addImportPath()

有很多东西可能会导致模块无法加载.您可以查看以下内容:

  1. qmldir中的模块标识符应与模块实际驻留的目录名称相同.例如,如果模块module TestModule在qmldir中具有模块标识符,则模块目录名必须为TestModule.
  2. 如果它是QML扩展插件(共享库),请确保插件的目录名与插件名相同.
  3. 导出QML2_IMPORT_PATH(确保2名称中有)env变量指向包含模块的目录.还有一种QQmlEngine::addImportPath方法,它将目录添加到列表中以查找插件.
  4. 如果它是一个qml扩展插件(共享库),那么它可能缺少依赖项.您可以通过Windows 上的Dependency WalkerlddLinux 上的命令进行检查.
  5. 设置QT_PLUGIN_PATH运行时变量可能有助于加载插件.它应该指向一个包含插件目录的目录,而不是插件目录本身.
  6. 您还可以启用跟踪以查看加载插件时发生的情况,以便更好地了解问题 - 导出QT_DEBUG_PLUGINS=1QML_IMPORT_TRACE=1环境变量

您还可以阅读以下链接:https: //doc.qt.io/qt-5/qtqml-modules-identifiedmodules.html


arx*_*ian 8

在我的情况下(我在qrc资源中有所有QML文件)工作也将qmldir添加到资源并调用QQmlApplicationEngine的方法addImportPath("qrc:/").

我的main.cpp看起来像:

QQmlApplicationEngine engine;
engine.addImportPath("qrc:/");
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
Run Code Online (Sandbox Code Playgroud)

我的.pro文件的重要部分如下所示:

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

QML_IMPORT_PATH += $$PWD
Run Code Online (Sandbox Code Playgroud)

我的qmldir:

module MyModule

MyItem          2.0 MyItem20.qml
MyItem          2.1 MyItem21.qml
Run Code Online (Sandbox Code Playgroud)

我的qrc:

<RCC>
    <qresource prefix="/MyModule">
        <file>MyItem20.qml</file>
        <file>MyItem21.qml</file>
        <file>qmldir</file>
    </qresource>
</RCC>
Run Code Online (Sandbox Code Playgroud)

最后我的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
    }
}
Run Code Online (Sandbox Code Playgroud)

QtCreator很高兴(没有强调组件和导入)并且加载了模块.希望这可以帮助.


Tra*_*s R 5

我想扩展arxarian 的答案——我认为这是集成模块的最佳技术——但在评论中无法满足这些想法,所以这里有一个新答案。

首先要了解 qml 模块及其关联资源是运行时实体,并且假定它们单独存在于相对于可执行文件的某个位置,除非它们包含在应用程序资源中,这一点很重要。通过将它们包含在资源中,它们仍然是运行时实体,但它们存在于应用程序二进制文件中的 qrc:/ 根路径下。模块的这种隐藏是我认为这是最好的技术的主要原因,除非您希望您的模块在部署后对修订开放,或者作为预编译插件独立部署(即,在动态链接的资源存储中)图书馆)。

所以这是我对arxarian 答案的重要元素的解释

  1. engine.addImportPath("qrc:/"); 在加载 qml 之前需要在 C++ 代码中指示引擎在应用程序资源存储中查找 qml 模块。
  2. RESOURCES += MyModule/mymodule.qrc需要在项目 (.pro) 文件中将模块的文件添加到应用程序资源存储中
  3. QML_IMPORT_PATH += $$PWD在项目文件中告诉Qt Creator从项目源代码树的根开始查找模块。就我而言,我必须将其设置为子目录(例如,“ui/modules”),因为我的模块目录从那里开始。导入路径应包括所有模块目录下的根目录。据我所知,此指令仅适用于 Qt Creator IDE,不会影响构建 - 这就是需要 #1 的原因。
  4. qmldir 文件的内容是所有 qml模块的标准内容,但它包含在模块的 .qrc 资源文件中并不直观,除非您考虑运行时存储发生了什么。它需要在 .qrc 中,以便将其包含在应用程序资源存储中,以便引擎可以在运行时找到它来定义模块。<qresource prefix="/MyModule">在模块的 .qrc 文件中定义了相对于应用程序资源存储中的 qrc:/root 的模块子目录。
  5. import MyModule <version>qml 中的语句现在设置成功。在启动时,引擎将在 qrc:/ 下的目录中找到模块,解析那里的 qmldir 文件以定义模块并从这些条目中建立名称和版本。

希望这有助于其他人了解发生了什么,如果我误解了什么,请告诉我。