插件编程
插件可以理解为动态库,一种固定接口的动态库.以下摘自网友的理解。代码参考自官方示例。
Qt插件本身是动态库,除此之外,它定义了一组专用的接口,从动态库中导出,供 Qt 的插件管理体系 发现和调用。当你选择 Qt 插件项目模板时, Qt Creator 会自动为你插入专用接口相关的模板代码。
假如你从一个白板做起,实现一个动态库,要想客户方调用,还是需要导出N多的函数。而 Qt
这种,只是它约定了你需要导出什么函数、什么类、怎样查询你导出的接口,它定义了一套规范而已。
接口定义
echo_interface.h
#pragma once
#include <QString>
#include <QObject>
class EchoInterface
{
public:
virtual ~EchoInterface() {}
virtual QString echo(const QString &message) = 0;
};
#define EchoInterface_iid "org.Examples.EchoInterface"
//接口申明.
Q_DECLARE_INTERFACE(EchoInterface, "org.Examples.EchoInterface") //类名.
插件调用
EchoPluginWindows.h
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_EchoPluginWindows.h"
#include "echo_interface.h"
class QString;
class QLineEdit;
class QLabel;
class QPushButton;
class QGridLayout;
class EchoPluginWindows : public QMainWindow
{
Q_OBJECT
public:
EchoPluginWindows(QWidget *parent = Q_NULLPTR);
private slots:
void send_echo();
private:
Ui::EchoPluginWindowsClass ui;
bool loadPlugin();
EchoInterface * echo_interface;
};
EchoPluginWindows.cpp
#include "EchoPluginWindows.h"
#include <QMessageBox>
#include <QDir>
#include <QPluginLoader>
#include <QtPlugin>
#include <QFileInfo>
#include <QDebug>
EchoPluginWindows::EchoPluginWindows(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
setWindowTitle("Echo Plugin Example");
if (!loadPlugin())
{
QMessageBox::information(this,"Error", "Could not load the plugin");
ui.lineEdit_msg->setEnabled(false);
ui.pushButton->setEnabled(false);
}
connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(send_echo()));
}
//发送消息槽函数
void EchoPluginWindows::send_echo()
{
QString text = echo_interface->echo(ui.lineEdit_msg->text());
ui.lineEdit_answer->setText(text);
}
//加载插件
bool EchoPluginWindows::loadPlugin()
{
QDir pluginDir(QApplication::applicationDirPath());
if (pluginDir.dirName().toLower() == "debug" || pluginDir.dirName().toLower() == "release")
{
qDebug() << "applicationDirPath:" << QApplication::applicationDirPath();
pluginDir.cdUp(); //回到上一级
pluginDir.cdUp(); //回到上一级
}
pluginDir.cd("plugin");
pluginDir.cd("Debug");
for each (QFileInfo file_name in pluginDir.entryInfoList(QDir::Files))
{
//插件加载器
QPluginLoader pluginLoader(file_name.absoluteFilePath());
QObject * plugin = pluginLoader.instance();
if (plugin)
{
echo_interface = qobject_cast<EchoInterface *>(plugin);
if (echo_interface)
{
return true;
}
}
}
return false;
}
插件库
按照插件接口定义,编写自己的插件库 echo_plugin.h
#pragma once
#include "echo_interface.h"
#include <QObject>
class EchoPlugin : public QObject, EchoInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "com.xhome.EchoPlugin") //插件元信息.
Q_INTERFACES(EchoInterface) //接口申明.
public:
QString echo(const QString &message) override;
};
echo_plugin.cpp
#include "echo_plugin.h"
#include <QtWidgets/QtWidgets>
//对接口进行实现即可.
QString EchoPlugin::echo(const QString &message)
{
return message;
}