当前位置: 首页 > news >正文

Qt5应用程序动态插件的使用 单独模块制作成插件/动态连接集成到主程序

QT5应用程序动态插件的使用

1 概要

在软件开发中可以将某些独立的功能模块作为插件(编译为库文件)来使用。这样做的插件就可以单独发布和升级而不需要修改主程序。
原理上是使用了C++的多态和QT元对象系统。插件功能的使用要分为主程序和插件程序两个部分。下面进行详细的介绍。
制作可扩展(可调用插件)的主程序,步骤如下:

  1. 定义一些列的操作接口(即抽象类,只有纯虚函数),用于插件内部方法的调用。
  2. 使用Q_DECLARE_INTERFACE()宏将步骤1定义的接口进行声明,注册到QT的元对象系统中。
  3. 在调用插件的地方使用QPluginLoader加载插件。
  4. 使用qobject_cast()将加载的插件转为相应的接口(此方法也可用于测试加载的插件是否为所需要的接口)。

插件程序的编写步骤如下:

  1. 声明自己的插件类,需要继承自QObject和需要实现的接口类(在制作可扩展应用程序的步骤1中定义的接口)。
  2. 使用Q_INTERFACES()宏向元对象系统声明所用到的接口。
  3. 使用Q_PLUGIN_METDATA()宏导出插件。

2 实例

实例项目分为两个子项目,主程序和插件程序,完整实例项目代码点击此处下载。

  • 主程序
    • myInterface接口文件
#ifndef MYINTERFACE_H
#define MYINTERFACE_H
#include <QObject>

class MyInterface
{
public:
    virtual void show() = 0;
};

Q_DECLARE_INTERFACE(MyInterface,"MyInterface.1")

#endif // MYINTERFACE_H

此接口只包含了纯虚函数show(),并用Q_DECLARE_INTERFACE对接口进行了声明。

    • 插件的调用方法
/* 定义接口指针用于操作插件 */
MyInterface *m_interface = NULL; 

/* 找到插件所存储的路径 */
QDir pluginDir(qApp->applicationDirPath());
pluginDir.cd("pluginDll");
foreach (QString fileName, pluginDir.entryList(QDir::Files)) {
    /* 遍历路径下的所有文件,当做插件进行加载 */
    QPluginLoader pluginLoader(pluginDir.absoluteFilePath(fileName));
    
    /* 加载插件并获取插件的实例,加载失败返回NULL */
    QObject *plugin = pluginLoader.instance();
    if (plugin) {
        /* 将插件转换为接口,失败返回NULL */
        m_interface = qobject_cast<MyInterface *>(plugin);
        if (m_interface)
            m_interface->show(); //调用方法
    
    }
}
  • 插件程序
    • plugin.h插件类定义
#ifndef PLUGIN_H
#define PLUGIN_H

#include <QObject>
#include "myInterface.h"

class plugin:public QObject,public MyInterface
{
    //以下三个宏不能少
	Q_OBJECT
	Q_INTERFACES(MyInterface)
	Q_PLUGIN_METADATA(IID "MyInterface.1" FILE "data.json")
	//Q_PLUGIN_METADATA宏一定要用到,如果没有元数据FILE可以不写直接写成下面这样
    //Q_PLUGIN_METADATA(IID "MyInterface.1")
public:
	void show();
};

#endif
    • plugin.cpp插件类实现
#include <QMessageBox>
#include "plugin.h"

void plugin::show()
{
    QWidget w;
    QMessageBox::warning(&w,"warning","test");
}
    • plugin.pro项目文件
TEMPLATE = lib  #插件编译为库文件
TARGET = plugin
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
CONFIG += plugin    #config中加入plugin表示动态插件
DEFINES += QT_DEPRECATED_WARNINGS

SOURCES += \
    plugin.cpp
HEADERS += \
        plugin.h
INCLUDEPATH += ../pluginMain

DESTDIR = ..bin/pluginDll
OBJECTS_DIR = ./obj
MOC_DIR = ./moc

该类继承自QObject和MyInterface接口,并实现了show函数(简单的显示一个告警对话框)。

相关文章:

  • 使用QT5创建动态库以及如何在程序运行时加载动态库
  • 装修经验分享
  • linux下socket常见问题整理
  • 奇偶校验的原理
  • CRC循环冗余校验原理
  • ceph基本环境搭建 使用cephadm
  • ceph-deploy常见问题处理
  • 解决linux下程序运行时无法找到动态库的问题error while loading shared libraries
  • Qt样式表的使用setStyleSheet
  • Qt实现关闭主/父窗口后同时关闭其他窗口的方法事件过滤器(eventFilter)的使用
  • StartUML4.0.1的使用方法
  • 结构型模式--Proxy代理模式
  • C++的Lambda表达式的用法
  • 微信小程序学习之rich-text的嵌入静态HTML
  • 微信小程序CSS Flexbox(弹性盒子)布局模块
  • $translatePartialLoader加载失败及解决方式
  • [iOS]Core Data浅析一 -- 启用Core Data
  • CSS进阶篇--用CSS开启硬件加速来提高网站性能
  • Debian下无root权限使用Python访问Oracle
  • docker容器内的网络抓包
  • JS创建对象模式及其对象原型链探究(一):Object模式
  • nginx(二):进阶配置介绍--rewrite用法,压缩,https虚拟主机等
  • Node.js 新计划:使用 V8 snapshot 将启动速度提升 8 倍
  • Object.assign方法不能实现深复制
  • VUE es6技巧写法(持续更新中~~~)
  • 阿里云容器服务区块链解决方案全新升级 支持Hyperledger Fabric v1.1
  • 仿天猫超市收藏抛物线动画工具库
  • 复杂数据处理
  • 关于Java中分层中遇到的一些问题
  • 海量大数据大屏分析展示一步到位:DataWorks数据服务+MaxCompute Lightning对接DataV最佳实践...
  • 开源中国专访:Chameleon原理首发,其它跨多端统一框架都是假的?
  • 利用DataURL技术在网页上显示图片
  • 买一台 iPhone X,还是创建一家未来的独角兽?
  • 前端知识点整理(待续)
  • 收藏好这篇,别再只说“数据劫持”了
  • 树莓派 - 使用须知
  • 项目管理碎碎念系列之一:干系人管理
  • 学习笔记DL002:AI、机器学习、表示学习、深度学习,第一次大衰退
  • 移动互联网+智能运营体系搭建=你家有金矿啊!
  • 走向全栈之MongoDB的使用
  • 深度学习之轻量级神经网络在TWS蓝牙音频处理器上的部署
  • ionic异常记录
  • ​ArcGIS Pro 如何批量删除字段
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • # Maven错误Error executing Maven
  • (10)Linux冯诺依曼结构操作系统的再次理解
  • (3)选择元素——(17)练习(Exercises)
  • (C语言)fread与fwrite详解
  • (多级缓存)缓存同步
  • (附源码)ssm高校志愿者服务系统 毕业设计 011648
  • (原創) 是否该学PetShop将Model和BLL分开? (.NET) (N-Tier) (PetShop) (OO)
  • (转)Android中使用ormlite实现持久化(一)--HelloOrmLite
  • (轉貼)《OOD启思录》:61条面向对象设计的经验原则 (OO)
  • *** 2003
  • ./configure,make,make install的作用(转)