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

结果演示

在这里插入图片描述

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