天天看点

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插件开发总结--插件间通信

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插件开发总结--插件间通信
connect(loader->instance(),SIGNAL(sendMsgToManager(PluginMetaData)),this,SLOT(recMsgFromPlugin(PluginMetaData)));      

三、插件通信使用

#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);
        }
    }

}