20.QT中插件編程

插件編程

 插件可以理解爲動態庫,一種固定接口的動態庫.以下摘自網友的理解。代碼參考自官方示例。

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;
}

結果演示

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章