我对Qt QML中的模块感到困惑。我已经阅读了所有文档,但它没有说明一些基本的想法。
据我所知,我可以将一堆QML文件放入目录并添加qmldir文件来描述已识别的模块。当我这样做并调整QML_IMPORT_PATH时,QtCreator很高兴并停止强调导入ModuleName 1.0行。
所以创作者很高兴,但它不起作用。我没有安装模块。 我的问题是:
对不起,对于所有这些问题,但这些模块的基础知识并不清楚。我不明白“模块”是仅仅是文件共享还是编译单元。
感谢您的帮助。
答案 0 :(得分:9)
我会尽力回答你的问题:
engine->addImportPath()
有很多东西可能会导致模块无法加载。您可以查看以下内容:
module TestModule
目录名称必须为TestModule
。QML2_IMPORT_PATH
(确保名称中有2
)env变量指向包含模块的目录。还有一个QQmlEngine::addImportPath
方法,它将目录添加到列表中以查找插件。ldd
命令进行检查。QT_PLUGIN_PATH
运行时变量可能有助于加载插件。它应该指向一个包含插件目录的目录,而不是插件目录本身。QT_DEBUG_PLUGINS=1
和QML_IMPORT_TRACE=1
环境变量您还可以阅读以下链接: https://doc.qt.io/qt-5/qtqml-modules-identifiedmodules.html
答案 1 :(得分:8)
在我的情况下(我在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很高兴(没有强调组件和导入)并加载了模块。 希望这会有所帮助。
答案 2 :(得分:3)
我希望扩展arxarian's answer - 我认为这是整合模块的最佳技巧 - 但不能将这些想法纳入评论中,所以这是一个新答案。
首先要了解qml模块及其相关资源是运行时实体,并假设它们分别存在于相对于可执行文件的某个位置,除非它们包含在应用程序资源中。通过将它们包含在资源中,它们仍然是运行时实体,但它们存在于应用程序二进制文件中的qrc:/ root路径下。这种模块的隐藏是我认为这是最好的技术的主要原因,除非你希望你的模块在部署后开放修改,或者可以独立部署为预编译插件(即,在动态链接的资源存储中)库)。
所以这是我对arxarian's answer的重要元素的解释:
engine.addImportPath("qrc:/");
,以指示引擎在应用程序资源存储中查找qml模块。RESOURCES += MyModule/mymodule.qrc
将模块的文件添加到application resource storage。QML_IMPORT_PATH += $$PWD
告诉 Qt Creator 从项目源树的根开始查找模块。在我的情况下,我必须将其设置为子目录(例如,“ui / modules”),因为我的模块目录在那里开始。导入路径应包括所有模块目录下的根。据我所知,这条指令仅适用于Qt Creator IDE,不会影响构建 - 这就是为什么需要#1的原因。<qresource prefix="/MyModule">
定义了相对于应用程序资源存储中的qrc:/ root的模块子目录。import MyModule <version>
语句现已成功设置。启动时,引擎会将模块放在qrc:/下的目录中,解析qmldir文件以定义模块并从这些条目中建立名称和版本。希望这有助于其他人了解正在发生的事情,如果我误解了任何内容,请告诉我。
答案 3 :(得分:0)
类似的问题花了我一些时间,所以我只在这里发布它,也许可以节省下一个家伙的精力。
我的问题是一个不可见的字符潜入了模块名称。可能通过复制和粘贴。这是我的问题:
错误输出示例:
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
一切看起来不错,显示的路径确实是正确的路径。那怎么了?
现在,将该路径复制到“终端”窗口:
file:///Users/<pathToProject>/MyProject/qml/MyModule/<feff>MyComponent.qml
就在这里,
"<feff>"
通过手动重新键入qmldir文件中的组件名称来解决此问题,从而有效地删除了不可见字符。
答案 4 :(得分:-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