文章目录

一、通信方案

Qt插件开发总结--插件间通信_qt


因为插件管理器和每一个插件都有关联(它负责插件的加载、卸载等等),那就让插件管理器来转发消息。


二、实现过程

1、在接口中增加消息结构体

struct PluginMetaData
{
QString from; //消息来源
QString dest; //消息去向
QString msg; //消息

QObject* object = nullptr;
QJsonObject info = QJsonObject();
};
Q_DECLARE_METATYPE(PluginMetaData); //确保类型可以通过信号槽传递

2、增加通信接口用于通信

virtual void recMsgFromManager(PluginMetaData) = 0; //接收来自插件管理器的消息
virtual void sendMsgToManager(PluginMetaData) = 0; //发送消息到插件管理器

Qt插件开发总结--插件间通信_通信接口_02


3、在插件中实现通信接口

插件A,插件B同理

#ifndef
#define

#include <QObject>
#include <QtPlugin>
#include <QDebug>
#include "../Main/PluginInterface.h"

class PluginA : public QObject,public PluginInterface
{
Q_OBJECT
Q_INTERFACES(PluginInterface)
Q_PLUGIN_METADATA(IID PluginInterface_iid FILE "pluginA.json")
public:
explicit PluginA(QObject *parent = nullptr);
void show_pluginA();

void recMsgFromManager(PluginMetaData metaData); //将此接口实现为方法功插件管理器调用

signals:
void sendMsgToManager(PluginMetaData); //将此接口实现为信号,用于和插件管理器绑定
};

#endif// PLUGINA_H
#include "pluginA.h"

PluginA::PluginA(QObject *parent) : QObject(parent)
{

}

void PluginA::show_pluginA()
{
qDebug()<<"这是插件A";
}

void PluginA::recMsgFromManager(PluginMetaData metaData) //a
{
qDebug()<<"插件A接收到消息:"<<metaData.msg;
}

4、在插件管理器中实现槽函数,并绑定信号-槽

public slots:
void recMsgFromPlugin(PluginMetaData);


void PluginManager::recMsgFromPlugin(PluginMetaData metaData)
{
auto loader = getPlugin(metaData.dest); //目标插件
if(loader) {
auto interface = qobject_cast<PluginInterface*>(loader->instance());
if(interface) {
interface->recMsgFromManager(metaData); //转发给对应的插件
}
}
}

Qt插件开发总结--插件间通信_qt_03

connect(loader->instance(),SIGNAL(sendMsgToManager(PluginMetaData)),this,SLOT(recMsgFromPlugin(PluginMetaData)));

Qt插件开发总结--插件间通信_通信接口_04


三、插件通信使用

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);

PluginManager::instance()->loadAllPlugins();
//qDebug()<<"allPluginsName: "<<PluginManager::instance()->allPluginsName();

QPluginLoader *loader1 = PluginManager::instance()->getPlugin("pluginA");
if(loader1) {
PluginInterface *pluginA = dynamic_cast<PluginInterface*>(loader1->instance());
if(pluginA) {
PluginMetaData m;
m.dest = "pluginB";
m.from = "pluginA";
m.msg = "插件A发给插件B的消息";
pluginA->sendMsgToManager(m);
}
}

QPluginLoader *loader2 = PluginManager::instance()->getPlugin("pluginB");
if(loader2) {
PluginInterface *pluginB = dynamic_cast<PluginInterface*>(loader2->instance());
if(pluginB) {
PluginMetaData m;
m.dest = "pluginA";
m.from = "pluginB";
m.msg = "插件B发给插件A的消息";
pluginB->sendMsgToManager(m);
}
}

}

Qt插件开发总结--插件间通信_通信接口_05