插件編程
插件可以理解爲動態庫,一種固定接口的動態庫.以下摘自網友的理解。代碼參考自官方示例。
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;
}