QT应用程序的插件
1、声明一个继承自QObject和提供接口的插件类
2、使用Q_INTEFACES()宏来告诉Qt元对象系统有关接口的情况
3、使用Q_PLUGIN_METADATA()宏导出插件
4、使用合适的.pro文件构建插件
调用QT插件
1、定义接口
2、加载插件
QT应用程序的插件
1、新建插件类和通信接口
在已有工程(插件工程)中新建插件类和通信接口
(1)通信接口:WidgetPluginInterface.h 用于与插件类进行通信,只有纯虚函数的类
(2)插件类:WidgetPluginDll.h 和WidgetPluginDll.cpp 实现插件功能,需要继承QObject和通信接口
通信接口
1.定义接口集(只有纯虚函数的类)
2.定义唯一的表示符
3.用宏Q_DECLARE_INTERFACE()将该接口告诉Qt元对象系统
#ifndef WIDGETPLUGININTERFACE_H
#define WIDGETPLUGININTERFACE_H
#include "QWidget"
//1.定义一个接口集(只有纯虚函数的类)
class WidgetPluginInterface{
public:
virtual ~WidgetPluginInterface(){}
virtual QWidget *getWidget() = 0;
virtual int Add() = 0;
virtual void SetInfo(QString str) = 0;
};
//2.唯一的标识符
#define WidgetPluginInterface_iid "Qt.WidgetPluginInterface"
//3.用宏Q_DECLARE_INTERFACE()将该接口告诉Qt元对象系统
QT_BEGIN_NAMESPACE
Q_DECLARE_INTERFACE(WidgetPluginInterface,WidgetPluginInterface_iid)
QT_END_NAMESPACE
#endif // WIDGETPLUGININTERFACE_H
插件类
1.需要继承自QObject和通信接口
2.用Q_PLUGIN_METADATA声明元数据
3.用Q_INTERAFACES宏声明接口类
(划重点:三步缺一不可)
WidgetPluginDll.h
#ifndef WIDGETPLUGINDLL_H
#define WIDGETPLUGINDLL_H
#include <QObject>
#include <WidgetPluginInterface.h>
#include <widget.h>
/**
* @brief The WidgetPluginDll class
* 插件类,继承自QObject和通信接口
*/
class WidgetPluginDll : public QObject,WidgetPluginInterface
{
//1.
Q_OBJECT
//2.使用Q_PLUGIN_METADATA声明(实例化该对象的)插件的元数据,元数据是插件的一部分
//即:QT识别的唯一标识符,与接口文件中的标识符一致
Q_PLUGIN_METADATA(IID "Qt.WidgetPluginInterface")
//3.用Q_INTERFACES宏来声明接口类
Q_INTERFACES(WidgetPluginInterface)
public:
explicit WidgetPluginDll(QObject *parent = nullptr);
QWidget* getWidget();
int Add();
void SetInfo(QString str);
private:
Widget *WidA = nullptr;
QWidget *WidR = nullptr;
int add = 0;
QString str;
};
#endif // WIDGETPLUGINDLL_H
WidgetPluginDll.cpp
#include "widgetplugindll.h"
WidgetPluginDll::WidgetPluginDll(QObject *parent)
: QObject{parent}
{
//定义主窗体
WidA = new Widget;
WidR = WidA;
}
/**
* @brief WidgetPluginDll::getWidget
* 获取窗体
* @return
*/
QWidget* WidgetPluginDll::getWidget()
{
return WidA;
}
/**
* @brief WidgetPluginDll::Add
* 实现加法
* @return
*/
int WidgetPluginDll::Add()
{
int a=0,b=0;
WidA->getAddValue(a,b);
add = a+b;
return add;
}
/**
* @brief WidgetPluginDll::SetInfo
* 设置Info
* @param str
*/
void WidgetPluginDll::SetInfo(QString str)
{
WidA->setInfo(str);
}
2、修改.pro文件
在pro文件中添加配置
#plugin
TEMPLATE = lib
CONFIG += plugin
TARGET = $$qtLibraryTarget(WidgetA)
3、调用插件类
新建一个工程,添加通信接口文件WidgetPluginInterface.h
(没错,这个接口文件,在插件工程和主工程中都需要用到)
加载插件
主工程的Widget.h文件
#include <WidgetPluginInterface.h>
#include <QDebug>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
//加载
bool LoadPlugin();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void on_pushButton_3_clicked();
private:
Ui::Widget *ui;
//定义接口
WidgetPluginInterface *pInterface = nullptr;
};
#endif // WIDGET_H
主工程的Widget.cpp文件
#include "widget.h"
#include "ui_widget.h"
#include "QMessageBox"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
if(!LoadPlugin()) {
QMessageBox::warning(this,"Error","Could not load the plugin");
}
}
Widget::~Widget()
{
delete ui;
}
/**
* @brief Widget::LoadPlugin
* 加载插件
* @return
*/
bool Widget::LoadPlugin(){
//此处必须使用绝对地址(相对地址会导致加载错误)
QString name = "D:/HanSVNLocal/Plugin/MainWidget/bin/WidgetA.dll";
QPluginLoader pluginLoader(name);
QObject *plugin = pluginLoader.instance();
qDebug() << pluginLoader.isLoaded();
qDebug() << "--->>>Lynn<<<---" << __FUNCTION__ << pluginLoader.errorString();
if (plugin) {
pInterface = qobject_cast<WidgetPluginInterface*>(plugin);
if (nullptr!=pInterface)
return true;
}
return false;
}
void Widget::on_pushButton_clicked()
{
pInterface->getWidget()->show();
}
void Widget::on_pushButton_2_clicked()
{
qDebug() << pInterface->Add();
}
void Widget::on_pushButton_3_clicked()
{
pInterface->SetInfo( ui->lineEdit->text() );
}