QT插件开发(2)-- 创建插件管理器统一管理插件

接上一篇

用上一篇创建插件的方法创建两个插件,分别命名为 Plugin01 和 Plugin02

改一下插件接口中的函数如下:

get_name()获取本插件的名称,管理器通过插件的名称来管理插件

Plugin01插件内容如下:

Plugin02大同小异:

插件管理器的用作加载插件、卸载插件、插件信息通信(作为插件间通信媒介,转发插件消息,插件间的通信通过插件管理器来处理)

以下是插件管理器,查考了这篇:https://blog.csdn.net/weixin_38416696/article/details/90068501

#include <QObject>
#include <QHash>
class QPluginLoader;

class PluginManager : public QObject
{
    Q_OBJECT

public:
    static PluginManager *instance()
    {
        if(m_instance == nullptr)
            m_instance = new PluginManager();
        return m_instance;
    }

    void loadAllPlugins();
    void loadPlugin(const QString &filepath);
    void unloadPlugin(const QString &filepath);
    void unloadAllPlugins();
    QPluginLoader* getPlugin(const QString &name);
    QVariant getPluginName(QPluginLoader *loader);

private:
    explicit PluginManager(QObject *parent = nullptr);
    ~PluginManager();

    QHash<QString, QPluginLoader *> m_loaders; //插件路径--QPluginLoader实例
    QHash<QString, QString> m_names; //插件路径--插件名称

    static PluginManager *m_instance;
    class GarbageCollector
    {
        ~GarbageCollector()
        {
            if (PluginManager::instance())
            {
                delete PluginManager::instance();
                PluginManager::m_instance = nullptr;
            }
        }
    };
    static GarbageCollector gc;
};

 

#include "pluginmanager.h"
#include <QPluginLoader>
#include <QDir>
#include <QDebug>
#include "PluginInterface.h"

PluginManager* PluginManager::m_instance;

PluginManager::PluginManager(QObject *parent) : QObject(parent)
{

}

PluginManager::~PluginManager()
{
    unloadAllPlugins();
}

//加载所有插件
void PluginManager::loadAllPlugins()
{
    QDir pluginsdir(QDir::currentPath());
    pluginsdir.cd("plugins");

    QFileInfoList pluginsInfo = pluginsdir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot);

    //加载插件
    for(QFileInfo fileinfo : pluginsInfo)
        loadPlugin(fileinfo.absoluteFilePath());
}

//加载其中某个插件
void PluginManager::loadPlugin(const QString &filepath)
{
    if(!QLibrary::isLibrary(filepath))
        return;

    //加载插件
    QPluginLoader *loader = new QPluginLoader(filepath);
    QString plugin_name;
    if(loader->load())
    {
        PluginInterface *plugin = qobject_cast<PluginInterface *>(loader->instance());
        if(plugin)
        {
            plugin_name = plugin->get_name();
            m_loaders.insert(filepath, loader);
            m_names.insert(filepath,plugin_name);
            qDebug()<<"插件名称:"<<plugin->get_name()<<"插件信息:"<<plugin->show_text();
        }
        else
        {
            delete loader;
            loader = nullptr;
        }
    }
    else
    {
        qDebug()<<"loadPlugin:"<<filepath<<loader->errorString();
    }
}

//卸载所有插件
void PluginManager::unloadAllPlugins()
{
    for(QString filepath : m_loaders.keys())
        unloadPlugin(filepath);
}

void PluginManager::unloadPlugin(const QString &filepath)
{
    QPluginLoader *loader = m_loaders.value(filepath);
    //卸载插件,并从内部数据结构中移除
    if(loader->unload())
    {
        m_loaders.remove(filepath);
        delete loader;
        loader = nullptr;
    }
}

//获取某个插件名称
QVariant PluginManager::getPluginName(QPluginLoader *loader)
{
    if(loader)
        return m_names.value(m_loaders.key(loader));
    else
        return "";
}

//根据名称获得插件
QPluginLoader *PluginManager::getPlugin(const QString &name)
{
    return m_loaders.value(m_names.key(name));
}

 然后和上一篇一样,创建一个普通的程序调用插件管理器,使用插件管理器查看效果,界面如下:

加载所有插件效果:

大功告成,两个插件都被加载了 

代码:https://download.csdn.net/download/kenfan1647/12382497

 

  • 6
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值