略
至少分为以下几个模块
插件式开发的好处在于,每个人可以独立的负责某个小的模块,这个模块还可以给其他的项目组用,而且很方便添加其他功能。所以QtPluginFramework项目的作用就是
#ifndef QtPluginInterface_H_
#define QtPluginInterface_H_
class CPluginFramework;
class QtPluginInterface
{
public:
virtual ~QtPluginInterface(){}
//
virtual void Start(QtPluginFramework* pPluginFramework) = 0;
//
virtual void Stop(QtPluginFramework* pPluginFramework) = 0;
};
Q_DECLARE_INTERFACE(QtPluginInterface, "Plugin.QtPluginInterface")
#endif
加载和卸载单个插件
在这里插入代码片
参考文献1
参考 qt 官方示例 Echo Plugin Example
怎样用 Qt 写个插件?
在项目中创建并使用自定义Qt插件【VS+Qt项目开发系列】(六)
使用ctkPluginFramework插件系统构建项目实战 **
ctk github
CTK框架使用简明教程
QT——插件的创建和使用
选择chose进入下一下页面,类型选择Qt Plugin,输入一个名称
首先需要一个虚接口 echointerface.h
,在插件工程和要运行插件的工程中都要使用
#ifndef ECHOINTERFACE_H
#define ECHOINTERFACE_H
#include
#include
//! [0]
class EchoInterface
{
public:
virtual ~EchoInterface() = default;
virtual QString echo(const QString &message) = 0;
};
QT_BEGIN_NAMESPACE
#define EchoInterface_iid "org.qt-project.Qt.Examples.EchoInterface"
Q_DECLARE_INTERFACE(EchoInterface, EchoInterface_iid)
QT_END_NAMESPACE
//! [0]
#endif
Q_DECLARE_INTERFACE() 向 Qt 元对象系统注册一下我写的这个接口。
该宏的第一个参数是接口类的名字,第二个参数是 iid(相当于一个身份证信息,可以随便写个字符串)。
至此,我的程序给外界提供了个公共接口,并且为了 Qt 编程方便还向元对象系统注册了一下。以后所有的插件都通过这个接口来扩展 app 的功能,当然也可以写更多的接口供外界调用。
接下来是写插件,要继承这个接口
echoplugin.h
#ifndef ECHOPLUGIN_H
#define ECHOPLUGIN_H
#include
#include
#include "echointerface.h"
//! [0]
class EchoPlugin : public QObject, EchoInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.Examples.EchoInterface" FILE "MyQtPlugin.json")
Q_INTERFACES(EchoInterface)
public:
QString echo(const QString &message) override;
};
//! [0]
#endif
echoplugin.cpp
#include "echoplugin.h"
//! [0]
QString EchoPlugin::echo(const QString &message)
{
return message;
}
//! [0]
然后编译生成,我们需要
MyQtPlugin.dll
MyQtPlugin.lib
echointerface.h
这三个文件
我们再新建一个工程 做一个界面
把刚才那三个文件复制到现在工程的目录下,把echointerface.h
添加到工程里面(右键添加现有文件)
echowindow.h
#ifndef ECHOWINDOW_H
#define ECHOWINDOW_H
#include
#include "echointerface.h"
QT_BEGIN_NAMESPACE
class QString;
class QLineEdit;
class QLabel;
class QPushButton;
class QGridLayout;
namespace Ui { class echowindow; }
QT_END_NAMESPACE
class echowindow : public QWidget
{
Q_OBJECT
public:
echowindow();
~echowindow();
private slots:
void sendEcho();
private:
void createGUI();
bool loadPlugin();
EchoInterface *echoInterface;
QLineEdit *lineEdit;
QLabel *label;
QPushButton *button;
QGridLayout *layout;
};
#endif // ECHOWINDOW_H
echowindow.cpp
#include "echowindow.h"
#include "ui_echowindow.h"
#include "echowindow.h"
#include
#include
#include
#include
#include
#include
#include
#include
//! [0]
echowindow::echowindow()
{
createGUI();
setLayout(layout);
setWindowTitle("Echo Plugin Example");
if (!loadPlugin()) {
QMessageBox::information(this, "Error", "Could not load the plugin");
lineEdit->setEnabled(false);
button->setEnabled(false);
}
}
//! [0]
//! [1]
void echowindow::sendEcho()
{
QString text = echoInterface->echo(lineEdit->text());
label->setText(text);
}
//! [1]
//! [2]
void echowindow::createGUI()
{
lineEdit = new QLineEdit;
label = new QLabel;
label->setFrameStyle(QFrame::Box | QFrame::Plain);
button = new QPushButton(tr("Send Message"));
connect(lineEdit, &QLineEdit::editingFinished,
this, &echowindow::sendEcho);
connect(button, &QPushButton::clicked,
this, &echowindow::sendEcho);
layout = new QGridLayout;
layout->addWidget(new QLabel(tr("Message:")), 0, 0);
layout->addWidget(lineEdit, 0, 1);
layout->addWidget(new QLabel(tr("Answer:")), 1, 0);
layout->addWidget(label, 1, 1);
layout->addWidget(button, 2, 1, Qt::AlignRight);
layout->setSizeConstraint(QLayout::SetFixedSize);
}
//! [2]
//! [3]
bool echowindow::loadPlugin()
{
QDir pluginsDir(QCoreApplication::applicationDirPath());
#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();
}
#endif
pluginsDir.cd("plugins");
const QStringList entries = pluginsDir.entryList(QDir::Files);
for (const QString &fileName : entries) {
QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
QObject *plugin = pluginLoader.instance();
if (plugin) {
echoInterface = qobject_cast<EchoInterface *>(plugin);
if (echoInterface)
return true;
pluginLoader.unload();
}
}
return false;
}
echowindow::~echowindow()
{
}
main.cpp
#include "echowindow.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
echowindow w;
w.show();
return a.exec();
}