接上一篇
用上一篇创建插件的方法创建两个插件,分别命名为 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