Qt5 编写应用程序扩展插件

Qt5 编写应用程序扩展插件,第1张

Qt5 编写应用程序扩展插件

目录

一、编写插件步骤

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

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

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

 三、编写一个实现插件


一、编写插件步骤 1.1. 通过插件使应用程序可扩展涉及以下步骤:
    定义一组用于与插件对话的接口(仅具有纯虚函数的类)。使用Q_DECLARE_INTERFACE ()宏向Qt的元对象系统声明该接口。在应用程序中使用QPluginLoader加载插件。使用qobject_cast()测试插件是否实现了给定的接口。
1.2. 编写一个实现插件的步骤:
    声明一个插件类,该类继承自QObject和该插件要提供的接口。使用Q_INTERFACES ()宏告诉Qt的元对象系统有关接口的信息。使用Q_PLUGIN_metaDATA ()宏导出插件。使用合适的.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 
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 
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 
#include      //包含插件装载头文件
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(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 
#include 
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文件夹】

 

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5702482.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存