2016-02-12 231 views
12

我对Qt QML中的模块感到困惑。我已阅读所有文档,但没有说明一些基本的想法。Qt5 QML模块未安装

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

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

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

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

感谢您的任何帮助。

回答

6

我会尽力回答您的问题:

  • 我觉得安装意味着它们位于正确的路径,所以
    他们可以在运行时被发现
  • 你不一定为此创建/构建一个QmlExtrensionPlugin。您也可以在一个 目录中使用qmldir作为模块中的普通QML文件来描述此模块。这是 分发您的代码的问题 - 如果您想隐藏代码,使用QmlExtensionPlugin提供编译的 模块。
  • 这些模块可以在资源系统中或作为磁盘上的文件,这取决于您。
  • 该应用程序会在预定义的路径模块 - 在应用程序的目录,在QT插件路径,在QML2_IMPORT_PATH,在目录中,您添加使用engine->addImportPath()

有一堆东西,可导致模块未被加载。您可以检查以下内容:在qmldir

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

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

+0

感谢解释,但我仍然主要是在黑暗中。我发现如果将'addImportPath'设置为* absolute *路径,它就可以工作。但我希望引用的QML是本地项目。相对路径失败,因为它们不能从生成的构建目录中运行。 我也想出了如何将模块+其资源编译为DLL。但我不知道如何加载这个DLL。安排它在导入路径不起作用,因为我认为该DLL需要qmldir。该DLL将注册其中的类型,但这将涉及首先加载它。种鸡和鸡蛋? –

+1

只需提供DLL插件的qmldir,它大约有3行,将qmldir放在插件旁边,将其全部放在具有正确名称的文件夹中,如我在答案中所述,并将该文件夹放在可执行文件的旁边。这应该工作。你尝试过吗? – rightaway717

+0

谢谢。经过漫长的道路和大量搜索,这有助于很多! – Malachi

2

在我的情况(我拥有qrc资源中的所有QML文件)也努力将qmldir添加到资源中,并调用QQmlApplicationEngine的addImportPath(“qrc:/”)方法。

我main.cpp中的样子:

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

我.pro文件的重要部分看起来像:

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

QML_IMPORT_PATH += $$PWD 

我qmldir:

module MyModule 

MyItem   2.0 MyItem20.qml 
MyItem   2.1 MyItem21.qml 

我QRC:

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

最后我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是幸福的(不强调成分和进口)和模块被加载。 希望这有助于。

-1

我有同样的问题,现在已经修复它。我找到了iOS的QML插件。有迹象表明,需要被照顾的几件事情:

1.插件亲文件需要加法:

URI = IosTestPulgin

# this for error: 
# static plugin for module “QtQuick” with name “IosTestPulgin” 
# has no metadata URI 
QMAKE_MOC_OPTIONS += -Muri=$$uri 

# thanks from:https://github.com/wang-bin/QtAV/issues/368 

2. QML插件qmldir文件需要如下附加行:

classname IosqmlpluginPlugin 
# for ERROR: Plugin iostestqmlplugin is missing a classname entry, 
# please add one to the qmldir file. 
# look for qt document http://doc.qt.io/qt-5.6/qtqml-modules-qmldir.html 

3客户端项目促文件需要一个除了像这样:

ios { 
    IOSTestPlugin_BUNDLE.files += $$files($$[QT_INSTALL_QML]/IosTestPulgin/qmldir) 
    IOSTestPlugin_BUNDLE.path = IosTestPulgin 
    QMAKE_BUNDLE_DATA += IOSTestPlugin_BUNDLE 
} 
# for ios error: module is not installed 
# this means external qml static plugin must add the plugin dir by manual 
# in the app root dir