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函数(简单的显示一个告警对话框)。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值