Qt5 编写应用程序扩展插件

目录

一、编写插件步骤

1.1. 通过插件使应用程序可扩展涉及以下步骤:

1.2. 编写一个实现插件的步骤:

二、编写通过插件使应用程序可扩展

 三、编写一个实现插件


一、编写插件步骤

1.1. 通过插件使应用程序可扩展涉及以下步骤:

  1. 定义一组用于与插件对话的接口(仅具有纯虚函数的类)。
  2. 使用Q_DECLARE_INTERFACE ()宏向Qt的元对象系统声明该接口。
  3. 在应用程序中使用QPluginLoader加载插件。
  4. 使用qobject_cast()测试插件是否实现了给定的接口。

1.2. 编写一个实现插件的步骤:

  1. 声明一个插件类,该类继承自QObject和该插件要提供的接口。
  2. 使用Q_INTERFACES ()宏告诉Qt的元对象系统有关接口的信息。
  3. 使用Q_PLUGIN_METADATA ()宏导出插件。
  4. 使用合适的.pro文件构建插件。

二、编写通过插件使应用程序可扩展

1. 新建一个子项目便于程序管理【文件->新建文件或项目->其它项目->子目录项目】

2. 名称随便命名即可,本次演示项目命名为【PluginProject】,然后指定目录

3. 指定构建套件默认即可

 4.完成并添加应用程序项目

5.选择【Application->Qt Widgets Application】

6.本次演示应用程序命名为【MainApp】默认mainwindow窗口类

 

 7.创建完成的项目结构如下,然后【MainApp右键->添加新的C++ Header File】命名为abstractinterface

 

8.定义一组用于与插件对话的接口(仅具有纯虚函数的类),使用Q_DECLARE_INTERFACE()宏向Qt的元对象系统声明该接口

#ifndef ABSTRACTINTERFACE_H
#define ABSTRACTINTERFACE_H
#include <QtPlugin>
class QWidget;
class AbstractInterface{
public:
    virtual ~AbstractInterface(){}  //必须定义虚析构函数
    virtual QWidget* createWidgetPlugin(QWidget *parent) const = 0;
};
#define AbstarctInterface_IID "qt.org.com.abstactinterface/1.0"   //iid随便命名当前项目独一无二即可
Q_DECLARE_INTERFACE(AbstractInterface,AbstarctInterface_IID)      //声明接口

#endif // ABSTRACTINTERFACE_H

 9.在mainwindow中使用QPluginLoader加载插件。使用qobject_cast()测试插件是否实现了给定的接口。

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
class AbstractInterface;
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
private:
    void loadPlugin();              //应用程序装载插件
private:
    AbstractInterface *mainInterface;      //插件类
};

#endif // MAINWINDOW_H

 

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "abstractinterface.h"
#include <QDir>
#include <QPluginLoader>     //包含插件装载头文件
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    loadPlugin();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::loadPlugin()
{
    //插件存放在应用程序目录下的plugin目录下,便于管理
    QDir pluginDir(qApp->applicationDirPath());  //定位应用程序目录

    if( pluginDir.cd("plugin") )                 //进入plugin,前提先创建plugin目录
    {
        for(auto fileName:pluginDir.entryList(QDir::Files))  //遍历目录下的文件
        {
            QFileInfo info(fileName);
            if(info.completeSuffix() == "dll" || info.completeSuffix() == "so")  //过滤后缀为dll或so的动态库文件
            {
                QPluginLoader load(pluginDir.absoluteFilePath(fileName));        //装载插件
                QObject *pluginObj = load.instance();                            //获取插件根对象
                if(pluginObj)
                {
                    mainInterface = qobject_cast<AbstractInterface *>(pluginObj);  //转换
                    mainInterface->createWidgetPlugin(ui->centralWidget);
                }
            }
        }
    }
}

 三、编写一个实现插件

1.【PluginProject->右键->新子项目->Application->Qt Widgets Application】

2. 项目名为【PluginApp】基类选择QWidget

3.完成后的项目结构

4.把PluginApp.pro中的相关配置更改如下

TARGET = PluginApp
TEMPLATE =lib                        #template改app为lib
CONFIG += plugin                     #增加plugin的配置
DESTDIR = ../MainApp/debug/plugin    #目标直接生成到MainApp的debug/plugin 
INCLUDEPATH += ../MainApp            #包含MainApp创建的abstractinterface.h

 5.【PluginApp->右键->新增C++ Class】命名为InterfaceImplement,并继承QObject

 6.接口实现类继承QObject以及抽象的AbstractInterface,使用Q_INTERFACES()宏告诉Qt的元对象系统有关接口的信息。使用Q_PLUGIN_METADATA ()宏导出插件。

#ifndef INTERFACEIMPLMENT_H
#define INTERFACEIMPLMENT_H

#include <QObject>
#include <abstractinterface.h>
class InterfaceImplment : public QObject, public AbstractInterface  //集成抽象接口
{
    Q_OBJECT
    Q_INTERFACES(AbstractInterface)                              //实现的接口
    Q_PLUGIN_METADATA(IID AbstarctInterface_IID)                 //导出接口后面的 FILE “jsonfile”可省略
public:
    explicit InterfaceImplment(QObject *parent = nullptr);
    ~InterfaceImplment() Q_DECL_OVERRIDE;
    QWidget *createWidgetPlugin(QWidget *parent) const Q_DECL_OVERRIDE;
};

#endif // INTERFACEIMPLMENT_H

7.构建PluginWidget对象,PluginWidget主要演示一个用户名和密码登录判断的简单示例

#include "interfaceimplment.h"
#include "pluginwidget.h"     //包含plugwidget头文件
InterfaceImplment::InterfaceImplment(QObject *parent) : QObject(parent)
{

}
InterfaceImplment::~InterfaceImplment()
{

}
QWidget *InterfaceImplment::createWidgetPlugin(QWidget *parent) const
{
    PluginWidget * w = new PluginWidget(parent);     //返回PluginApp实现的界面类
    return w;
}

8. 构建【PluginProject】项目,无错误将在MainApp/debug/plugin中生成PluginApp动态库,

然后单独运行MainAPP出现下面界面,表示插件扩展成功【在MainApp/debug中手动创建plugin文件夹】

 

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值