Qt的插件开发
写代码都是从不会到会,那么写博客也是同样的道理。从不会到会最实用的办法就是模仿了。关于Qt的知识很多都是学习了CSDN的一位大神 一去二三里。关于Qt插件的开发,我们也从他的文章里面抽丝剥茧,把最本质、最实用的东西提取出来拿到我们的文章里面消化吸收。
关于Qt插件的部分,他一共写了5篇之多,可见插件系统在Qt整个框架中的重要性。因为Qt本身就是一个通过pluginManager组织起来的插件系统。我们就不再啰嗦文章里面已有的内容,仅仅将文章列表给出来,之后我们要做的是理解、消化、吸收,这个在软件开发里面叫做”重构“。
1.深入理解插件系统
4.Qt插件定义
插件相对于dll的好处
- 插件可以做到灵活的加载
- 当dll不存在的时候中程序也不会崩溃(这个应该是最大的好处了吧)
demo地址https://gitee.com/guiguzicom/Demo/tree/master/QtPluginTest,实现了简单的插件
构建插件的几个步骤:
编写扩展 Qt 应用程序的插件,涉及以下步骤:
- 声明一个继承自 QObject 和插件想要提供的接口的插件类
- 使用 Q_INTERFACES() 宏来告诉 Qt 元对象系统有关接口的情况
- 使用 Q_PLUGIN_METADATA() 宏导出插件
Q_PLUGIN_METADATA(IID IPerson_iid FILE "programmer.json") 用该宏导出插件,programmer.json文件描述插件的属性
{
"author" : "wzx",
"date" : "2019/11/28",
"name" : "personPlugin",
"version" : "1.0.0",
"dependencies" : []
}
json的这样编写
4.使用合适的 .pro 文件构建插件
TEMPLATE = lib
CONFIG += plugin
在pro文件中添加上面两个配置
通过插件使应用程序可扩展,涉及以下步骤:
- 定义一组用于与插件通信的接口(只有纯虚函数的类)
- 使用 Q_DECLARE_INTERFACE() 宏来告诉 Qt 元对象系统有关接口的情况
- 在应用程序中使用 QPluginLoader 加载插件
- 使用 qobject_cast() 来测试插件是否实现了指定的接口
上面这些是构造Qt应用程序的插件的,还有一种更底层的时候构建Qt本身的插件的。那个就比较复杂一点,由于没有用到且我们还需要接着探索qml的插件是如何构建的,所以我们就先把”扩展Qt本身的插件“放一放,暂且不表。接下来我们研究qml插件的构造。
构造插件本身的过程其实不难,分为以下步骤:
1.创建子项目工程

2.添加一个QML工程子项


这个设计成用来动态加载我们的插件
3.创建插件工程
忘记截图了~
在工程里面添加一个QML文件,然后把

这三个文件拷贝到上面的Test工程的新建的plugin目录。当然最后还是要拷贝到工程的build路径下的,具体路径参见 -4.使用 篇
4.使用
1)导入插件目录,使Qt能够识别到
QQmlApplicationEngine engine;
engine.addImportPath(QCoreApplication::applicationDirPath()+"/plugin");
这个是在debug生成的exe同级目录下的plugin文件夹下,放入插件目录
2)dir文件的内容如下:
module com.mycompany.qmlcomponents
plugin QmlPlugin
WItem 1.0 qrc:/MyPlugin.qml
模块名称
插件名
这个是用到插件时候的定义的类型,可以理解为把
qrc:/MyPlugin.qml
这个目录下的qml文件当做WItem的1.0版本的component。之所以写"qrc:/"这种资源文件路径是因为这个qml文件被编译到插件动态库中了,
已经在这里了,不能用传统的相对路径的形式。传统的路径格式,编译器会从addImportPath的路径去寻找。但是这种路径会遇到一个问题:
”应用程序输出“会报”在qmldir文件中,使用非相对URL“ qrc:/MyPlugin.qml”指定组件“ WItem”。 qmldir文件中的URL应相对于qmldir文件的目录。”意思在qmdir定义组件必须要用相对qmdir文件的路径来标识qml文件,这里肯定不能这样用。
这个是运行的时候报的提示(不是错误),但是最后的结果是正确的
3)
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.5 import com.mycompany.qmlcomponents 1.0
import MyPlugin 1.0 Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World") MyPlugin{
width:200
height:200
Component.onCompleted: {
console.log("MyPlugin name= ", name)
}
}
MyItem{
width:200
height:200
Component.onCompleted: {
console.log("MyPlugin name= ", name)
}
} WItem{ }
}
使用方法是这样的。MyPlugin和MyItem是我们在c++中定义并且注册过的类,WItem是我们在qmldir中把插件工程中的qml文件重新加上版本号注册之后的component的名称。如果插件里面有多个qml文件定义的组件,都可以按照这种方法添加。
WItem在QtCreator中并没有高亮显示,据说要qmltypes文件才能够显示显示。这个文件要用Qt的qmlplugindump 工具生成。本人尝试用
qmlplugindump -v -nonrelocatable MyPlugin 1.0 . > plugins.qmltypes
这条命令生成,但是不成功
,网上试了各种办法也还是不行。反正最后程序能正常运行,高亮提示的先放一放啦~~
tips:添加到插件工程qrc里面的qml文件在调用该插件的工程里面也可以通过相同的
qrc:/main.qml
qrc路径里面获取到。这个应该是添加到qrc里面的资源,Qt通过相同的组织二进制的方式在dll里面读取到。但是如果插件工程和Demo工程有文件重复就会导致文件路径的二义性,会出错。
Qt的插件开发的更多相关文章
- Qt学习大全
这边文章的目的是把自己之前写的关于Qt的文章整理归纳成一个Qt学习的专栏,会提供之前文章的导航,同时也会留一些坑待自己日后填. 1.Qt 元对象系统 2.Qt的信号和槽 3.Qt的插件开发 4.Qml ...
- qt creator源码全方面分析(2-1)
目录 coding-style.html 提交代码 二进制兼容性和源代码兼容性 代码构造 格式化 利用标识符 空格 大括号 圆括号 换行符 声明 命名空间 模式与实践 命名空间 传递文件名 插件扩展点 ...
- Qt插件开发入门(两种方法:High-Level API接口,Low-Level API接口)
Qt中为我们提供了两种开发插件的方式.一种是使用High-Level API接口,一种是使用Low-Level API接口.所谓High-Level API 是指通过继承Qt为我们提供的特定的插件基类 ...
- Qt——自定义属性
一.Qt中的属性 属性是指窗口或控件的属性,比如opacity属性表示“透明度”,geometry指的是“位置和大小”,pos属性代表“位置”. qt中的控件有自带的属性,我们也可以自己定义属性. Q ...
- Maya插件开发的几种方式归纳
目前仅仅是一时兴趣,想要探索一下Maya插件开发的具体方法,但因为没有时间所以只起了个头 首先来到Autodesk Developer Network http://usa.autodesk.com/ ...
- QT插件+ROS 2 新建项目
一QT插件开发ROS,http://www.ncnynl.com/archives/201701/1277.html 二QT开发遇到问题http://blog.csdn.net/u013453604/ ...
- Qt——元对象和属性机制
http://www.cnblogs.com/hellovenus/p/5582521.html 一.元对象 元对象(meta object)意思是描述另一个对象结构的对象,比如获得一个对象有多少成员 ...
- Qt自定义插件编程小结
qt自定义组件开发步骤演示.以下所有步骤的前提是自己先编译Qtcreator源码,最好生成release版的QtCreator,否则自定义的插件嵌入QtCreator会失败!!!(这个网上教程很多) ...
- Qt安装与入门
一.Qt SDK1.2安装 准备QtSdk-offline-win-x86-v1_2_1.exe离线安装包. 安装QtSDK时注意不要有中文路径,空格以及特殊字符.可以自定义选择组件安装,也可以默认安 ...
随机推荐
- 海量数据处理的 Top K 相关问题
Top-k的最小堆解决方法 问题描述:有N(N>>10000)个整数,求出其中的前K个最大的数.(称作Top k或者Top 10) 问题分析:由于(1)输入的大量数据:(2)只要前K个,对 ...
- Nginx的启动、停止等命令
Windows下Nginx的启动.停止等命令 在Windows下使用Nginx,我们需要掌握一些基本的操作命令,比如:启动.停止Nginx服务,重新载入Nginx等,下面我就进行一些简单的介绍.1.启 ...
- javascript 箭头函数的使用 初学者必看
为了保证可读性,本文采用意译而非直译.另外,本文版权归原作者所有,翻译仅用于学习. 本文我们介绍箭头(arrow)函数的优点. 更简洁的语法我们先来按常规语法定义函数: 1 2 3 4 5 funct ...
- 巧用XML格式数据传入存储过程转成表数据格式
1.首先将后台数据转成对应的XML数据格式 /// <summary> /// 集合转XML数据格式 /// </summary> /// <param name=&qu ...
- 运行 jcontrol 报 libXext.so.6: cannot open shared object file 错误
需要安装额外库: yum install libXext.x86_64 yum install libXrender.x86_64 yum install libXtst.x86_64
- FDD-LTE上下行带宽一样的,为什么上下行流量差别这么大
转:https://zhidao.baidu.com/question/923940070377297579.html 虽然FD系统,上下行使用的带宽一样,但是上下行的信号编码效率完全不同.上行信号( ...
- django 配置文件settings.py 设置模板
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'dj ...
- Ubuntu16.04, CUDA8 CUDNN6 下安装 Tensorflow-gpu, Keras, Pytorch, fastai
如何访问tensorflow官方网站 tensorflow官方网站变为:https://tensorflow.google.cn/ 安装深度学习框架 0. ubuntu查看CUDA和cuDNN版本 C ...
- python中实现一个简单的进度条
import time def progress(n,a): m = int(n / a * 100) x = int(n / a * 10) time.sleep(0.2) #只是为了让进度条明显 ...
- 文件读写(三)利用FileStream类操作字节数组byte[]、BinaryFormatter、内存流MemoryStream
一.Stream类概述 在.NET Framework中,文件和流是有区别的.文件是存储在磁盘上的数据集,它具有名称和相应的路径.当打开一个文件并对其进行读/写时,该文件就称为流(stream).但是 ...