0. 前言
Qt 有自己的插件系統, 使用插件框架開發程序, 便於擴展和管理, 插件實際上是動態庫, 個人理解是與動態庫的區別是有一個插件管理器, 使用相同的調用約定.
1. 環境
Qt 4.8.7 + win10
2. 功能
這個demo的功能是發送一個Message字符串到插件的函數, 並返回顯示
3.目錄
源碼路徑: Github下載源碼地址
E:PluginApp
│ list.txt
│ PluginApp.pro
│ PluginApp.pro.user
│
├─EchoPlugin
│ echoplugin.cpp
│ echoplugin.h
│ EchoPlugin.pro
│ main.cpp
│
└─MainWindow
echointerface.h
main.cpp
MainWindow.pro
widget.cpp
widget.h
可以看到, 使用了子項目開發模式, PluginApp 內有兩個子項目, EchoPlugin和MainWindow
EchoPlugin: 插件子項目, 生成dll插件
MainWindow: 主窗口 , 調用插件
4. 用法
先不說細節, 只講大概的思路
EchoPlugin
<1> pro中插件的相應配置
<2> 創建插件類, 實現相關的方法
MainWindow
<1> 定義插件的調用頭文件, 裏面是插件類的聲明, 都是虛方法, 用於在創建插件對象時重載
<2> 加載插件類並使用
5. 源碼
上部分核心代碼
MainWindow子項目
echointerface.h 聲明插件虛方法的頭文件
#ifndef ECHOINTERFACE_H
#define ECHOINTERFACE_H
#include <QString>
class EchoInterface
{
public:
virtual ~EchoInterface() {}
virtual QString echo(const QString &message) = 0;
};
#define EchoInterface_lib "Example.Plugin.EchoInterface"
QT_BEGIN_NAMESPACE
Q_DECLARE_INTERFACE(EchoInterface, EchoInterface_lib)
QT_END_NAMESPACE
#endif // ECHOINTERFACE_H
loadPlugin() 加載插件
bool Widget::loadPlugin()
{
bool ret = true;
//獲取當前應用程序所在路徑
QDir pluginsDir(qApp->applicationDirPath());
qDebug() << pluginsDir;
#if defined(Q_OS_WIN)
if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release")
pluginsDir.cdUp();
#elif defined(Q_OS_MAC)
if (pluginsDir.dirName() == "MacOS")
{
pluginsDir.cdUp();
pluginsDir.cdUp();
pluginsDir.cdUp();
}
#elif defined(Q_OS_LINUX)
pluginsDir.cdUp();
#endif
//切換到插件目錄
pluginsDir.cdUp();
pluginsDir.cd("plugins");
qDebug() << pluginsDir;
//遍歷plugins目錄下所有文件
foreach (QString fileName, pluginsDir.entryList(QDir::Files))
{
qDebug() << fileName;
QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
QObject *plugin = pluginLoader.instance();
if (plugin)
{
//插件名稱
QString pluginName = plugin->metaObject()->className();
//對插件初始化
if(pluginName == "EchoPlugin")
{
echoInterface = qobject_cast<EchoInterface *>(plugin);
if (echoInterface)
ret = true;
break;
}
else
{
ret = false;
}
}
}
return ret;
}
sendEcho 使用插件方法
void Widget::sendEcho()
{
QString text = echoInterface->echo(lineEdit->text());
label->setText(text);
}
EchoPlugin 插件子項目
echointerface.h
#ifndef ECHOPLUGIN_H
#define ECHOPLUGIN_H
#include <QObject>
#include <QtPlugin>
#include "echointerface.h"
class EchoPlugin : public QObject, public EchoInterface
{
Q_OBJECT
Q_INTERFACES(EchoInterface)
public:
explicit EchoPlugin(QObject *parent = 0);
QString echo(const QString &message);
};
#endif // ECHOPLUGIN_H
echointerface.cpp
#include "echoplugin.h"
EchoPlugin::EchoPlugin(QObject *parent) :
QObject(parent)
{
}
QString EchoPlugin::echo(const QString &message)
{
return message;
}
Q_EXPORT_PLUGIN2(EchoPlugin, EchoPlugin)