目录
一、编写插件步骤
1.1. 通过插件使应用程序可扩展涉及以下步骤:
1.2. 编写一个实现插件的步骤:
二、编写通过插件使应用程序可扩展
三、编写一个实现插件
一、编写插件步骤 1.1. 通过插件使应用程序可扩展涉及以下步骤:
- 定义一组用于与插件对话的接口(仅具有纯虚函数的类)。使用Q_DECLARE_INTERFACE ()宏向Qt的元对象系统声明该接口。在应用程序中使用QPluginLoader加载插件。使用qobject_cast()测试插件是否实现了给定的接口。
- 声明一个插件类,该类继承自QObject和该插件要提供的接口。使用Q_INTERFACES ()宏告诉Qt的元对象系统有关接口的信息。使用Q_PLUGIN_metaDATA ()宏导出插件。使用合适的.pro文件构建插件。
1. 新建一个子项目便于程序管理【文件->新建文件或项目->其它项目->子目录项目】
2. 名称随便命名即可,本次演示项目命名为【PluginProject】,然后指定目录
3. 指定构建套件默认即可
4.完成并添加应用程序项目
5.选择【Application->Qt Widgets Application】
6.本次演示应用程序命名为【MainApp】默认mainwindow窗口类
7.创建完成的项目结构如下,然后【MainApp右键->添加新的C++ Header File】命名为abstractinterface
8.定义一组用于与插件对话的接口(仅具有纯虚函数的类),使用Q_DECLARE_INTERFACE()宏向Qt的元对象系统声明该接口
#ifndef ABSTRACTINTERFACE_H #define ABSTRACTINTERFACE_H #includeclass QWidget; class AbstractInterface{ public: virtual ~AbstractInterface(){} //必须定义虚析构函数 virtual QWidget* createWidgetPlugin(QWidget *parent) const = 0; }; #define AbstarctInterface_IID "qt.org.com.abstactinterface/1.0" //iid随便命名当前项目独一无二即可 Q_DECLARE_INTERFACE(AbstractInterface,AbstarctInterface_IID) //声明接口 #endif // ABSTRACTINTERFACE_H
9.在mainwindow中使用QPluginLoader加载插件。使用qobject_cast()测试插件是否实现了给定的接口。
#ifndef MAINWINDOW_H #define MAINWINDOW_H #includeclass AbstractInterface; namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); private: Ui::MainWindow *ui; private: void loadPlugin(); //应用程序装载插件 private: AbstractInterface *mainInterface; //插件类 }; #endif // MAINWINDOW_H
#include "mainwindow.h" #include "ui_mainwindow.h" #include "abstractinterface.h" #include三、编写一个实现插件#include //包含插件装载头文件 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); loadPlugin(); } MainWindow::~MainWindow() { delete ui; } void MainWindow::loadPlugin() { //插件存放在应用程序目录下的plugin目录下,便于管理 QDir pluginDir(qApp->applicationDirPath()); //定位应用程序目录 if( pluginDir.cd("plugin") ) //进入plugin,前提先创建plugin目录 { for(auto fileName:pluginDir.entryList(QDir::Files)) //遍历目录下的文件 { QFileInfo info(fileName); if(info.completeSuffix() == "dll" || info.completeSuffix() == "so") //过滤后缀为dll或so的动态库文件 { QPluginLoader load(pluginDir.absoluteFilePath(fileName)); //装载插件 QObject *pluginObj = load.instance(); //获取插件根对象 if(pluginObj) { mainInterface = qobject_cast(pluginObj); //转换 mainInterface->createWidgetPlugin(ui->centralWidget); } } } } }
1.【PluginProject->右键->新子项目->Application->Qt Widgets Application】
2. 项目名为【PluginApp】基类选择QWidget
3.完成后的项目结构
4.把PluginApp.pro中的相关配置更改如下
TARGET = PluginApp TEMPLATE =lib #template改app为lib ConFIG += plugin #增加plugin的配置 DESTDIR = ../MainApp/debug/plugin #目标直接生成到MainApp的debug/plugin INCLUDEPATH += ../MainApp #包含MainApp创建的abstractinterface.h
5.【PluginApp->右键->新增C++ Class】命名为InterfaceImplement,并继承QObject
6.接口实现类继承QObject以及抽象的AbstractInterface,使用Q_INTERFACES()宏告诉Qt的元对象系统有关接口的信息。使用Q_PLUGIN_metaDATA ()宏导出插件。
#ifndef INTERFACEIMPLMENT_H #define INTERFACEIMPLMENT_H #include#include class InterfaceImplment : public QObject, public AbstractInterface //集成抽象接口 { Q_OBJECT Q_INTERFACES(AbstractInterface) //实现的接口 Q_PLUGIN_metaDATA(IID AbstarctInterface_IID) //导出接口后面的 FILE “jsonfile”可省略 public: explicit InterfaceImplment(QObject *parent = nullptr); ~InterfaceImplment() Q_DECL_OVERRIDE; QWidget *createWidgetPlugin(QWidget *parent) const Q_DECL_OVERRIDE; }; #endif // INTERFACEIMPLMENT_H
7.构建PluginWidget对象,PluginWidget主要演示一个用户名和密码登录判断的简单示例
#include "interfaceimplment.h" #include "pluginwidget.h" //包含plugwidget头文件 InterfaceImplment::InterfaceImplment(QObject *parent) : QObject(parent) { } InterfaceImplment::~InterfaceImplment() { } QWidget *InterfaceImplment::createWidgetPlugin(QWidget *parent) const { PluginWidget * w = new PluginWidget(parent); //返回PluginApp实现的界面类 return w; }
8. 构建【PluginProject】项目,无错误将在MainApp/debug/plugin中生成PluginApp动态库,
然后单独运行MainAPP出现下面界面,表示插件扩展成功【在MainApp/debug中手动创建plugin文件夹】
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)