1. QML插件
- 纯QML插件,即将QML文档转化成动态链接库(windows下是dll,linux下是.so,mac下是dyso)
- 基于C++的扩展插件,比如自定义类的属性、方法,以便在QML中使用它们。这种插件一般使用得不多,原因是有点脱裤子放屁
下面分别针对这两种情况做下介绍,以及遇到的坑的说明。这里介绍是基于Qt Creator,使Qt版本是Qt5.15。
2. 基于C++扩展插件
首先创建Qt Quick插件工程,如下:

从向导可以看出,创建插件其实就是封装动态库。

这里工程的名称叫MyPlugin。

这里的命名都是默认的,MyItem是C++类的名称,URI表示模块名称,比如import QtQuick 2.0,这里的Q tQuick就是模块名称。关于模块命名与使用上,会有一些坑要注意,后面再具体解释。

这里以Release方式编译就可以了。

这里下接点完成即创建好这个工程。

创建好的工程目录结构是这样的,myplugin_plugin.cpp是用来注册QML Type给QML使用的
myitem.cpp是一个类,这个类可以导出给QML使用,具体导出在myplugin_plugin.cpp类的构造函数里用qmlRegisterType注册。如果有更多的C++类,比如A,B…等类,只需要在这个工具里添加新类即可,然后在myplugin_plugin.cpp里注册。

这是MyPlugin.pro配置文件内容,这里的uri就是导出的模块名称,也就是创建工程时默认的,所以这里名称也可自定义。TARGET是最终编译出来的库名称,比如MyPlugin.dll。DISTFILES类似指定安装路径,这里默认是在编译build路径下面,所以也可以自定义。TEMPLATE是模板,这里是lib表示是编译生成动态库。

编译后生成dll动态库,这样在应用APP中就可以导入使用了,具体怎么导入后面介绍。
以下是Qt官方的帮助文档,值得一看:
https://doc.qt.io/qt-5/qtqml-modules-cppplugins.html
3. 基于QML扩展插件

在当前工程里添加资源qrc

qrc文件名习惯与工程一致。

带有qrc资源的工程目录结构,同时添加了资源前缀为/。

与添加qrc类似的方式,添加qml文档。

这里文件名是要以大写字母开头的,因为Qt规定模块要以大写字母开头。

因为上一步已经创建了qrc资源,所这里默认是将qml文档归档到qrc下面的,当然不想放到qrc下面也可以,这里还是建议放到qrc下面,便于导出DLL时隐藏QML源码的内容(安全考虑啊,你辛苦创建的一个控件,怎么能开放随便开放呢)。

添加了qml文档后的目录结构是这样的,同时在qml文档中我们自定义了一个Rectange属性。

注册的方式与前面C++扩展插件类似,qmlRegisterType这个函数是重载的,所以它有两种用法。这里MyRect与MyItem都是注册的QML Type,可以在QML里使用它们。

Qt Creator不是万能的,qmldir就是一个指路人,这个可以参考Qt官方文档介绍,qmldir文档怎么写,都有严格的格式的哦。
https://doc.qt.io/archives/qt-5.6/qtqml-modules-qmldir.html
上面1.0是模块的版本。
到这里基于QML的扩展插件也介绍完了,直接编译下同样生了dll库。

这里有没有发现多了个MyRect_qml.cpp,这个是Qt Quick Compiler的功劳,它把QML源码直接编译进了binary的库中去了,是不是这样发布插件时就不用把qml文档一起发布出去了,答案是肯定的,是不是很安全啊。下面关于Qt Quick Compiler官网介绍很详细,可以看看。它不仅是可以隐藏qml,像js脚本同样可以被隐藏,具体看下面链接吧。
https://doc.qt.io/QtQuickCompiler/
4. 应用APP中使用
我们可以创建一个Qt Quick Application来测试上面的插件是否有效啊。

上面是创建的工程模板具体不一一介绍了,这里创建的是一个Empty的工程。

工程的目录结构是这样的,这里在pro配置中要注意一个宏QML_IMPORT_PATH,它指定了插件的位置哦,另外$$PWD是表示工程源码目录,也就是main.cpp所在目录啊。

与上面的宏类似,这里用函数addImportPath把插件的路径告诉系统啊,系统插件路径有哪些啊,可以用另一个函数查看哦。qDebug() <<emgine. importPathList();可以发现我们新添加的路径也在里面为。
['D:/py/qml2exe', 'D:/Users/Python/Python39', 'qrc:/qt-project.org/imports', 'D:/Users/Python/Python39/lib/site-packages/PySide2/qml']


这里开始说坑了,看到那个com文件夹了吗,哪个里面还有两个嵌套文件夹.

那个文件夹展开是这样的了,看到没,与模块名称一样哦,这就是我说的坑,如果你随便创建一个文件夹,把dll和qmldir放进去是没有用的。会报下面这个错误,说模块没有安装啊。
16:05:02: Starting D:\prj\build-MyPluginTest-Desktop_Qt_5_15_2_MSVC2019_32bit-Release\release\MyPluginTest.exe ...
QQmlApplicationEngine failed to load component
qrc:/main.qml:3:1: module "JxesPlugin" is not installed
所以,切记,调用插件时一定要放好位置啊

看看Qt官方,插件对应的文件夹名称与模块名是一样一样的哦。到这里坑就填好了。
5. qmltypes的妙用
它类似一个配置文件,主要用来给Qt Creator之类的开发IDE提供代码补齐、高亮显示、错误检查等功能。所以没有这个文件也不影响插件的使用哦,只是写代码时有点不爽哈。
为了生成这个文件,Qt工具包里提供了一个很好用的工具qmlplugindump,下面就打开Qt Creator的控制台,看看这个工具吧。

这里有两个控制台终端哦,一个是32-bit一个是64-bit,这个不用解释了吧。我这里选32-bit这个介绍。

这是打开的窗口哦。

下面就以前面的测试程序做示意,进入这个目录如上所示,并且以com.mycompany. qmlcomponents这个插件为例了。

注意下当前目录是在测试程序根目录下哦,qmlcomponents后面的两个路径要注意它们的不同哦,这个也是容易掉坑的地方哦,与上面提到的坑有点类似呢。

看上去还是很顺利哦,成功生成了qmltypes文件哦。另外,这个文件也可以自己写的,按照它规定的语法结构去写就可以了,通常在交叉编译的环境中只能手工写了,因为这个工具还不支持交叉环境的使用哦。先看下官网介绍吧。
https://doc.qt.io/archives/qt-5.6/qtqml-modules-qmldir.html
下面看看这个文件里有什么。

下面再次强调下那个坑吧,假如我把路径修改成不是它的模块名称,比如D:\prj\MyPluginTest\com\mycompany\qmlcomponents1,就在最后一个目录名后加一个1改名。

看到了,提示不匹配哦(说明:>后面指示的导出路径可以随便指定,由于qmltypes文件是要与qmldir、dll它们放在一起的,所以直接指示导出路径即为它们所在的目录)。我们一共提到两个坑,两个坑都是同样的原因造成的,重要的事说三遍吧:
插件(动态库与qmldir)要放在以模块名称命名的文件夹下面!!!
插件(动态库与qmldir)要放在以模块名称命名的文件夹下面!!!
插件(动态库与qmldir)要放在以模块名称命名的文件夹下面!!!
说明:
在PySide2下使用QML扩展插件失败,针对Python语言的插件,在后面再做介绍。下面是使用时的失败信息:


本文详细介绍了如何在Qt中制作QML插件,包括基于C++的扩展插件和纯QML插件的创建过程,以及在应用中如何使用这些插件。通过实例演示了创建Qt Quick插件工程的步骤,讨论了qmldir、qmltypes文件的作用,并着重强调了模块命名和文件组织结构的重要性,以避免在使用插件时遇到的问题。
425

被折叠的 条评论
为什么被折叠?



