一、媒介
插件大抵可分为:功能性插件、界面插件;一个软件由一堆插件堆起来,一定难以克制插件间相互引用,比方:插件A调用了插件C中的功能,那么插件A就依靠插件C,以是在步调启动加载插件时,就应该先加载插件C,再加载插件A。
假如插件A是用于初始化的模块,插件C是用于检测软件序列合法性的模块,假如先加载插件A,并直接调勤奋能模块,那么检测软件序列合法性这部分功能就是缺失的,以是必须要检测插件间的依靠关系,并分列插件加载序次,才气使得软件功能正常。
但是插件依靠,不能形成死锁,比方:有向环
- 图1:先加载插件B和插件C,再加载插件A,即可;
- 图2:先加载插件C,再加载插件B,再加载插件A,即可;
- 图3:先加载插件C,再加载插件B,再加载插件A,即可;
- 图4:加载插件A必要插件B,加载插件B必要插件C,加载插件C必要插件A,就形成死锁了;
二、根本计谋
插件元数据中有一项:dependencies,这个就是用来标识该插件依靠的插件,比方:插件A依靠插件B、插件C
- {
- "author" : "Wang_JC",
- "date" : "2022/02/16",
- "name" : "pluginA",
- "version" : "1.0.0",
- "des" : "这是一个插件A",
- "dependencies" : ["pluginB:1.0.0","pluginC:1.0.0"],
- "menu" : "menuFile",
- "action" : ["action_A1","action_A2","action_A3"],
- "widget" : "tabWidget"
- }
复制代码 我们在主步调中嗅探、自动加载插件:
在加载插件的时间,我们可以读取插件元数据中的插件依靠信息,然后检测依靠;假如存在依靠,那就暂不加载;假如不存在,那就直接加载。
检测插件是否存在依靠:可以遍历当前插件依靠项
比及自动加载插件全部竣事后,我们再查抄依靠插件栈内是否有还未加载的插件,有的话,再手动加载一下:
三、效果展示
弄了4个插件:A、B、C、D,依靠关系如下:
- 插件A:依靠插件B和插件C
- 插件B:无依靠
- 插件C:无依靠
- 插件D:无依靠
以是加载插件时,插件B和插件C必须要在插件A之间加载,插件D无所谓
四、关键代码
4.1、主步调
- #ifndef MAINWINDOW_H
- #define MAINWINDOW_H
- #include <QMainWindow>
- #include <QDebug>
- #include "PluginManager.h"
- #include <QDir>
- #include <QMenuBar>
- #include <QToolBar>
- #include <QTabWidget>
- #include <QWidget>
- #include <QHBoxLayout>
- #include <QLabel>
- #include "./Widget/speeddashbroad.h"
- QT_BEGIN_NAMESPACE
- namespace Ui { class MainWindow; }
- QT_END_NAMESPACE
- class MainWindow : public QMainWindow
- {
- Q_OBJECT
- public:
- MainWindow(QWidget *parent = nullptr);
- ~MainWindow();
- void Init_UI();
- void recvMsgFromManager(PluginMetaData metaData);
- QMenuBar* menuBar;
- QMenu* menuFile;
- QMenu* menuEdit;
- QMenu* menuView;
- QMenu* menuTool;
- QTabWidget* tabWidget;
- public:
- SpeedDashBroad* sdb;
- signals:
- void sendMsgToManager(PluginMetaData);
- private slots:
- void slot_PluginAction_MenuBar(QString menu,QStringList actionList); //添加插件菜单栏Action
- void slot_PluginsAction_trigger(bool isChecked); //响应插件Action
- void slot_PluginWidget(QPluginLoader*,QString); //添加插件widget
- private:
- Ui::MainWindow *ui;
- };
- #endif // MAINWINDOW_H
复制代码- #include "mainwindow.h"
- #include "ui_mainwindow.h"
- MainWindow::MainWindow(QWidget *parent)
- : QMainWindow(parent)
- , ui(new Ui::MainWindow)
- {
- ui->setupUi(this);
- Init_UI();
- //传递主程序指针给插件管理器
- PluginManager::instance()->m_mainWin = this;
- //绑定主程序和插件管理器消息信号槽
- connect(this,&MainWindow::sendMsgToManager,PluginManager::instance(),&PluginManager::recMsgFromPlugin);
- //嗅探到的所有插件
- qDebug()<<"嗅探插件: "<<PluginManager::instance()->CK_allPluginsName().keys();
- //加载所有插件
- foreach(QString pluginName , PluginManager::instance()->CK_allPluginsName().keys()) {
- PluginManager::instance()->loadPlugin(PluginManager::instance()->CK_allPluginsName().value(pluginName));
- }
- //加载所有插件
- // PluginManager::instance()->loadAllPlugins();
- //加载存在依赖稍候处理的插件
- while(!PluginManager::instance()->m_remainPlugin.isEmpty()) {
- QString plugin_filePath = PluginManager::instance()->m_remainPlugin.pop();
- qDebug()<<endl<<endl<<"加载存在依赖稍候处理的插件: "<<plugin_filePath;
- PluginManager::instance()->loadPlugin(plugin_filePath);
- }
- //加载其中某个插件
- // PluginManager::instance()->loadPlugin(PluginManager::instance()->CK_allPluginsName().value("pluginA"));
- // PluginManager::instance()->loadPlugin(PluginManager::instance()->CK_allPluginsName().value("pluginB"));
- // PluginManager::instance()->loadPlugin(PluginManager::instance()->CK_allPluginsName().value("pluginC"));
- // PluginManager::instance()->loadPlugin(PluginManager::instance()->CK_allPluginsName().value("pluginD"));
- // QPluginLoader *loader1 = PluginManager::instance()->getPlugin("pluginA");
- // PluginInterface* pluginInterface1 = qobject_cast<PluginInterface *>(loader1->instance());
- // pluginInterface1->showSomeThing("新增接口API");
- // QPluginLoader *loader2 = PluginManager::instance()->getPlugin("pluginB");
- // PluginInterface* pluginInterface2 = qobject_cast<PluginInterface *>(loader2->instance());
- // pluginInterface2->showSomeThing("新增接口API");
- // //通信测试
- // //================================================================================
- // 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);
- // }
- // }
- // //------------------------------
- // if(loader2) {
- // PluginInterface *pluginB = dynamic_cast<PluginInterface*>(loader2->instance());
- // if(pluginB) {
- // PluginMetaData m1;
- // m1.dest = "mainWin";
- // m1.from = "pluginB";
- // m1.msg = "插件B发给主程序的消息";
- // pluginB->sendMsgToManager(m1);
- // }
- // }
- // //------------------------------
- // PluginMetaData m2;
- // m2.dest = "pluginA";
- // m2.from = "mainWin";
- // m2.msg = "主程序发给插件A的消息";
- // this->sendMsgToManager(m2);
- }
- MainWindow::~MainWindow()
- {
- delete ui;
- }
- void MainWindow::Init_UI()
- {
- QWidget* p = takeCentralWidget(); //删除中央窗体
- if (p) {
- delete p;
- }
- setDockNestingEnabled(true); //允许嵌套dock
- //-------------------------------------------------
- menuBar = new QMenuBar(this);
- menuFile = new QMenu("文件", this);
- menuBar->addMenu(menuFile);
- this->setMenuBar(menuBar);
- menuEdit = new QMenu("编辑", this);
- menuBar->addMenu(menuEdit);
- this->setMenuBar(menuBar);
- menuView = new QMenu("视图", this);
- menuBar->addMenu(menuView);
- this->setMenuBar(menuBar);
- menuTool = new QMenu("工具", this);
- menuBar->addMenu(menuTool);
- this->setMenuBar(menuBar);
- connect(PluginManager::instance(),&PluginManager::sig_actions,this,&MainWindow::slot_PluginAction_MenuBar);
- //-------------------------------------------------
- tabWidget = new QTabWidget(this);
- tabWidget->setMinimumSize(1000, 800); // 设置最小宽高
- setCentralWidget(tabWidget); // 指定为中心窗口
- connect(PluginManager::instance(),&PluginManager::sig_widget,this,&MainWindow::slot_PluginWidget);
- //-------------------------------------------------
- sdb = new SpeedDashBroad;
- tabWidget->addTab(sdb,"表盘");
- }
- void MainWindow::slot_PluginAction_MenuBar(QString menu,QStringList actionList)
- {
- QAction * action = nullptr;
- if(menu == QString::fromLocal8Bit("menuFile")) {
- for(int i=0; i<actionList.size(); ++i) {
- action = new QAction(QIcon(), actionList.at(i), this);
- menuFile->addAction(action);
- connect(action,&QAction::triggered,this,&MainWindow::slot_PluginsAction_trigger);
- }
- }
- if(menu == QString::fromLocal8Bit("menuEdit")) {
- for(int i=0; i<actionList.size(); ++i) {
- action = new QAction(QIcon(), actionList.at(i), this);
- menuEdit->addAction(action);
- connect(action,&QAction::triggered,this,&MainWindow::slot_PluginsAction_trigger);
- }
- }
- if(menu == QString::fromLocal8Bit("menuView")) {
- for(int i=0; i<actionList.size(); ++i) {
- action = new QAction(QIcon(), actionList.at(i), this);
- menuView->addAction(action);
- connect(action,&QAction::triggered,this,&MainWindow::slot_PluginsAction_trigger);
- }
- }
- if(menu == QString::fromLocal8Bit("menuTool")) {
- for(int i=0; i<actionList.size(); ++i) {
- action = new QAction(QIcon(), actionList.at(i), this);
- menuTool->addAction(action);
- connect(action,&QAction::triggered,this,&MainWindow::slot_PluginsAction_trigger);
- }
- }
- }
- void MainWindow::recvMsgFromManager(PluginMetaData metaData)
- {
- qDebug()<<"主程序接收到消息:"<<metaData.msg;
- }
- void MainWindow::slot_PluginsAction_trigger(bool isChecked)
- {
- QAction* action = qobject_cast<QAction*>(sender());
- for(int i=0; i<PluginManager::instance()->_actionMap.size(); ++i) { //遍历插件管理器action映射表
- if(PluginManager::instance()->_actionMap.at(i).action == action->text()) { //映射表中匹配到Action对应的方法
- PluginInterface* plugin = qobject_cast<PluginInterface *>(PluginManager::instance()->_actionMap.at(i).plugin->instance()); //获取该action对应的接口指针
- if(plugin) {
- for(int j=0; j<plugin->_actionName.size(); ++j) { //遍历该接口指针内的action名字
- if(plugin->_actionName[j] == action->text()) {
- plugin->_actionFunction[j](true);
- break;
- }
- }
- }
- break;
- }
- }
- }
- void MainWindow::slot_PluginWidget(QPluginLoader* loader,QString widget)
- {
- if(widget == QString::fromLocal8Bit("tabWidget")) {
- PluginInterface* pluginInterface = qobject_cast<PluginInterface *>(loader->instance());
- QString pluginName = pluginInterface->_Plugin_Name;
- QWidget* widget = pluginInterface->_widget;
- if(widget) {
- tabWidget->addTab(widget,pluginName);
- }
- }
- //也可以预留布局接入点,插件UI嵌入,看自己需求
- if(widget == QString::fromLocal8Bit("xxxLayout")) {
- }
- }
复制代码 4.2、插件管理器
- #ifndef PLUGINMANAGER_H
- #define PLUGINMANAGER_H
- #include "../Plugin_Interface/PluginInterface.h"
- #include <QObject>
- #include <QPluginLoader>
- #include <QVariant>
- #include <QAction>
- #include <QStack>
- class MainWindow;
- typedef struct manager_action_map
- {
- QString action;
- QPluginLoader* plugin;
- }MANAGER_ACTION_MAP;
- class PluginManager : public QObject
- {
- Q_OBJECT
- public:
- explicit PluginManager(QObject *parent = nullptr);
- ~PluginManager();
- static PluginManager *instance(){
- if(m_instance==nullptr)
- m_instance=new PluginManager();
- return m_instance;
- }
- MainWindow* m_mainWin;
- QStack<QString> m_remainPlugin;
- public:
- QList<MANAGER_ACTION_MAP> _actionMap;
- void deal_metaData(QPluginLoader* loader,QJsonObject& json);
- public:
- //扫描JSON文件中的插件元数据
- void scanMetaData(const QString &filepath,QJsonObject& json);
- //加载所有插件
- void loadAllPlugins();
- //加载其中某个插件
- void loadPlugin(const QString &filepath);
- //卸载所有插件
- void unloadAllPlugins();
- //卸载某个插件
- void unloadPlugin(const QString &filepath);
- //获取所有插件名称
- QList<QVariant> allPluginsName();
- //获取所有插件
- QList<QPluginLoader *> allPlugins();
- //获取某个插件名称
- QVariant getPluginName(QPluginLoader *loader);
- //根据名称获得插件
- QPluginLoader* getPlugin(const QString &name);
- //获取库中所有插件名称
- QHash<QString,QString> CK_allPluginsName();
- signals:
- void sig_actions(QString,QStringList);
- void sig_widget(QPluginLoader*,QString);
- public slots:
- void recMsgFromPlugin(PluginMetaData);
- void slot_test();
- private:
- static PluginManager *m_instance;
- class PluginsManagerPrivate;
- PluginsManagerPrivate *managerPrivate;
- };
- #endif // PLUGINMANAGER_H
复制代码- #include "PluginManager.h"
- #include <QDir>
- #include <QCoreApplication>
- #include <QJsonArray>
- #include <QDebug>
- #include "mainwindow.h"
- PluginManager* PluginManager::m_instance=nullptr;
- class PluginManager::PluginsManagerPrivate
- {
- public:
- PluginsManagerPrivate()
- {
- m_names.clear();
- m_versions.clear();
- m_dependencies.clear();
- m_loaders.clear();
- m_dependencies_temp.clear();
- }
- ~PluginsManagerPrivate(){}
- QHash<QString, QVariant> m_names; //插件路径--插件名称
- QHash<QString, QVariant> m_versions; //插件路径--插件版本
- QHash<QString, QVariantList> m_dependencies; //插件路径--插件额外依赖的其他插件
- QHash<QString, QPluginLoader *> m_loaders; //插件路径--QPluginLoader实例
- QHash<QString, QVariantList> m_dependencies_temp;
- bool check(const QString &filepath) //插件依赖检测
- {
- //qDebug()<<QString("=============== bool check(%1) ===============").arg(filepath);
- bool status = true;
- foreach (QVariant item, m_dependencies_temp.value(filepath)) {
- QString dependencyPluginInfo = item.toString();
- // 依赖的插件名称、版本、路径
- QStringList List = dependencyPluginInfo.split(':');
- QString name_str = List[0];
- QString version_str = List[1];
- QString path = m_names.key(name_str);
- qDebug()<<"=== 插件依赖信息 ===";
- qDebug()<<"name_str: "<<name_str;
- qDebug()<<"version_str: "<<version_str;
- qDebug()<<"path: "<<path;
- QVariant name = QVariant(name_str);
- QVariant version = QVariant(version_str);
- /********** 检测插件是否依赖于其他插件 **********/
- // 先检测插件名称
- if (!m_names.values().contains(name)) {
- qDebug() << "=== 插件" << filepath <<" 缺少依赖插件:" << name.toString();
- status = false;
- continue;
- }
- // 再检测插件版本
- if (m_versions.value(path) != version) {
- qDebug() << "=== 依赖插件: " << name.toString() << "当前版本为: "
- << m_versions.value(m_names.key(name)).toString() << "但是需要依赖插件版本为: " << version.toString();
- status = false;
- continue;
- }
- // 然后,检测被依赖的插件是否还依赖于另外的插件
- if (!check(path)) {
- qDebug() << "=== 依赖插件:" << name.toString() << "又依赖: " << path;
- status = false;
- continue;
- }
- }
- //qDebug()<<"status: "<<status;
- return status;
- }
- };
- PluginManager::PluginManager(QObject *parent) : QObject(parent)
- {
- managerPrivate = new PluginsManagerPrivate;
- }
- PluginManager::~PluginManager()
- {
- delete managerPrivate;
- }
- void PluginManager::loadAllPlugins()
- {
- QDir pluginsDir(qApp->applicationDirPath()); //pluginsDir: "../build-xxx-debug/debug"
- if(pluginsDir.dirName().toLower() == "debug" ||
- pluginsDir.dirName().toLower() == "release") {
- pluginsDir.cdUp(); //pluginsDir: "../build-xxx-debug"
- pluginsDir.cdUp(); //pluginsDir: "../"
- }
- pluginsDir.cd("plugins");
- QFileInfoList pluginsInfo = pluginsDir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot);
- //加载插件
- for(QFileInfo fileinfo : pluginsInfo)
- loadPlugin(fileinfo.absoluteFilePath());
- }
- void PluginManager::scanMetaData(const QString &filepath,QJsonObject& json)
- {
- //判断是否为库(后缀有效性)
- if(!QLibrary::isLibrary(filepath))
- return;
- if(managerPrivate->m_names.keys().contains(filepath)) {
- //qDebug()<<QString("插件: %1 已加载,退出!!!").arg(filepath);
- return;
- }
- //获取元数据
- QPluginLoader *loader = new QPluginLoader(filepath);
- //qDebug()<<loader->metaData().keys();
- json = loader->metaData().value("MetaData").toObject();
- // for(int i=0; i<json.keys().size(); ++i) {
- // qDebug()<<json.keys().at(i)<< " : "<<json.value(json.keys().at(i));
- // }
- managerPrivate->m_names.insert(filepath, json.value("name").toVariant());
- managerPrivate->m_versions.insert(filepath, json.value("version").toVariant());
- managerPrivate->m_dependencies.insert(filepath, json.value("dependencies").toArray().toVariantList());
- //qDebug()<<"dependencies: "<<json.value("dependencies").toArray().toVariantList();
- //qDebug()<<"managerPrivate->m_dependencies: "<<managerPrivate->m_dependencies.values();
- delete loader;
- loader = nullptr;
- }
- void PluginManager::loadPlugin(const QString &filepath)
- {
- //库文件类型检测
- if(!QLibrary::isLibrary(filepath))
- return;
- //读取当前插件依赖
- qDebug()<<"===========================================================================";
- QPluginLoader *loader_temp = new QPluginLoader(filepath);
- QJsonObject json_temp = loader_temp->metaData().value("MetaData").toObject();
- managerPrivate->m_dependencies_temp.insert(filepath, json_temp.value("dependencies").toArray().toVariantList());
- //qDebug()<<"managerPrivate->m_dependencies_temp: "<<managerPrivate->m_dependencies_temp;
- delete loader_temp;
- loader_temp = nullptr;
- qDebug()<<"@@@ 当前加载插件: "<<filepath;
- //检测依赖
- if(!managerPrivate->check(filepath)) {
- qDebug()<<"当前插件存在依赖,入栈,稍候处理: "<<filepath;
- m_remainPlugin.push(filepath);
- //清空当前插件依赖
- managerPrivate->m_dependencies_temp.clear();
- return;
- }
- //清空当前插件依赖
- managerPrivate->m_dependencies_temp.clear();
- //检测当前插件是否已加载
- if(managerPrivate->m_loaders.keys().contains(filepath)) {
- qDebug()<<"当前插件已加载!!!";
- return;
- }
- //加载插件
- QPluginLoader *loader = new QPluginLoader(filepath);
- if(loader->load()) {
- PluginInterface *plugin = qobject_cast<PluginInterface *>(loader->instance());
- if(plugin) {
- //检测元信息
- QJsonObject json;
- scanMetaData(filepath,json);
- deal_metaData(loader,json);
- managerPrivate->m_loaders.insert(filepath, loader);
- connect(loader->instance(),SIGNAL(sendMsgToManager(PluginMetaData)),
- this,SLOT(recMsgFromPlugin(PluginMetaData)));
- //绑定
- if(plugin->_Plugin_Name == QString::fromLocal8Bit("PluginA")) {
- //qDebug()<<"plugin->_Plugin_Name: "<<plugin->_Plugin_Name;
- connect(loader->instance(),SIGNAL(sig_test()),
- this,SLOT(slot_test()));
- }
- plugin->Info(QString(" %1 加载成功!").arg(plugin->_Plugin_Name));
- }else {
- delete loader;
- loader = nullptr;
- }
- }else{
- qDebug()<<"loadPlugin:"<<filepath<<loader->errorString();
- }
- }
- void PluginManager::unloadAllPlugins()
- {
- for(QString filepath : managerPrivate->m_loaders.keys())
- unloadPlugin(filepath);
- }
- void PluginManager::unloadPlugin(const QString &filepath)
- {
- if(!managerPrivate->m_loaders.keys().contains(filepath)) {
- return;
- }
- QPluginLoader *loader = managerPrivate->m_loaders.value(filepath);
- //卸载插件,并从内部数据结构中移除
- if(loader->unload()) {
- PluginInterface *plugin = qobject_cast<PluginInterface *>(loader->instance());
- if(plugin) {
- plugin->Info("插件卸载成功!");
- managerPrivate->m_loaders.remove(filepath);
- delete loader;
- loader = nullptr;
- }
- }
- }
- QList<QPluginLoader *> PluginManager::allPlugins()
- {
- return managerPrivate->m_loaders.values();
- }
- QList<QVariant> PluginManager::allPluginsName()
- {
- return managerPrivate->m_names.values();
- }
- QVariant PluginManager::getPluginName(QPluginLoader *loader)
- {
- if(loader)
- return managerPrivate->m_names.value(managerPrivate->m_loaders.key(loader));
- else
- return "";
- }
- QPluginLoader *PluginManager::getPlugin(const QString &name)
- {
- return managerPrivate->m_loaders.value(managerPrivate->m_names.key(name));
- }
- void PluginManager::recMsgFromPlugin(PluginMetaData metaData)
- {
- //和主程序通信
- //------------------------------------------------------------
- if(metaData.dest == QString::fromLocal8Bit("mainWin")) {
- if(m_mainWin) {
- m_mainWin->recvMsgFromManager(metaData);
- }
- return;
- }
- //和插件通信
- //------------------------------------------------------------
- auto loader = getPlugin(metaData.dest); //目标插件
- if(loader) {
- auto interface = qobject_cast<PluginInterface*>(loader->instance());
- if(interface) {
- interface->recMsgFromManager(metaData); //转发给对应的插件
- }
- }
- }
- void PluginManager::slot_test()
- {
- //qDebug()<<"触发槽函数: PluginManager::slot_test()";
- }
- QHash<QString,QString> PluginManager::CK_allPluginsName()
- {
- QDir pluginsDir(qApp->applicationDirPath()); //pluginsDir: "../build-xxx-debug/debug"
- if(pluginsDir.dirName().toLower() == "debug" ||
- pluginsDir.dirName().toLower() == "release") {
- pluginsDir.cdUp(); //pluginsDir: "../build-xxx-debug"
- pluginsDir.cdUp(); //pluginsDir: "../"
- }
- pluginsDir.cd("plugins");
- QFileInfoList pluginsInfo = pluginsDir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot);
- //库中插件
- QHash<QString,QString> pluginNames;
- for(QFileInfo fileinfo : pluginsInfo){
- if(fileinfo.fileName().contains(".dll")) {
- QString pluginName = fileinfo.fileName().mid(0,fileinfo.fileName().size()-4);
- QString pluginPath = fileinfo.filePath();
- pluginNames.insert(pluginName,pluginPath);
- }
- }
- return pluginNames;
- }
- void PluginManager::deal_metaData(QPluginLoader* loader,QJsonObject& json)
- {
- QString name;
- if(json.keys().contains("name")) {
- QJsonValue JValue = json.value("name").toString();
- name = JValue.toString();
- }
- //------------------------------------------------------------
- QString menu;
- QStringList actionList;
- if(json.keys().contains("menu")) {
- QJsonValue JValue = json.value("menu").toString();
- menu = JValue.toString();
- }
- if(json.keys().contains("action")) {
- QJsonArray JArray = json.value("action").toArray();
- for(int i=0;i<JArray.size();++i) {
- actionList << JArray.at(i).toString();
- MANAGER_ACTION_MAP manager_action_map;
- manager_action_map.action = JArray.at(i).toString();
- manager_action_map.plugin = loader;
- _actionMap.push_back(manager_action_map);
- }
- }
- QStringList dependencies_List;
- if(json.keys().contains("dependencies")) {
- QJsonArray JArray = json.value("dependencies").toArray();
- for(int i=0;i<JArray.size();++i) {
- dependencies_List << JArray.at(i).toString();
- }
- }
- //qDebug()<<"dependencies_List: "<<dependencies_List;
- //------------------------------------------------------------
- if(!menu.isEmpty() && !actionList.empty()) {
- emit sig_actions(menu,actionList);
- }
- //------------------------------------------------------------
- //------------------------------------------------------------
- QString widget;
- if(json.keys().contains("widget")) {
- QJsonValue JValue = json.value("widget").toString();
- widget = JValue.toString();
- if(!widget.isEmpty()) {
- sig_widget(loader,widget); //发送:插件对象、主界面预留接入点
- }
- }
- //------------------------------------------------------------
- }
复制代码 4.3、插件A
pluginA.json
- {
- "author" : "Wang_JC",
- "date" : "2022/02/16",
- "name" : "pluginA",
- "version" : "1.0.0",
- "des" : "这是一个插件A",
- "dependencies" : ["pluginB:1.0.0","pluginC:1.0.0"],
- "menu" : "menuFile",
- "action" : ["action_A1","action_A2","action_A3"],
- "widget" : "tabWidget"
- }
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金 |