系统设计

搭建插件框架的好处

分析

至少分为以下几个模块

  1. 需要至少一个界面插件,用于展示界面
  2. 需要一些功能插件,为界面提供所需功能,例如FTP功能,网络服务,数据库等等
  3. 需要一个插件用于管理其他插件,插件间的通信,维护等等
  4. 需要一个启动程序作为入口

流程

  1. mainApp项目作为启动整个程序的入口,生成传统意义上的exe文件,点击它启动软件
  2. 启动之后,需要加载管理插件的插件项目(命名为QtPluginFramework)
  3. QtPluginFramework加载各个插件:包括界面插件,功能插件等等
  4. 界面显示,用户互动产生命令调用功能插件
  5. 用户退出界面,QtPluginFramework卸载各个插件
  6. mainApp退出

QtPluginFramework项目

分析

插件式开发的好处在于,每个人可以独立的负责某个小的模块,这个模块还可以给其他的项目组用,而且很方便添加其他功能。所以QtPluginFramework项目的作用就是

  1. 定义一个公共接口QtPluginInterface,所有的插件都必须实现这个接口
  2. 加载和卸载单个插件的功能,定义QtPlugin类
  3. 集中管理所有插件的功能,定义QtPluginManage类
  4. 插件间的通信功能,定义QtEvents类
  5. 最后定义QtPluginFramework类,集成以上所有功能

实现

QtPluginInterface

#ifndef QtPluginInterface_H_
#define QtPluginInterface_H_class CPluginFramework;
class QtPluginInterface
{public:virtual ~QtPluginInterface(){}//virtual void Start(QtPluginFramework* pPluginFramework) = 0;//virtual void Stop(QtPluginFramework* pPluginFramework) = 0;
};Q_DECLARE_INTERFACE(QtPluginInterface, "Plugin.QtPluginInterface")#endif

QtPlugin

加载和卸载单个插件

在这里插入代码片

参考文献

参考文献1
参考 qt 官方示例 Echo Plugin Example
怎样用 Qt 写个插件?
在项目中创建并使用自定义Qt插件【VS+Qt项目开发系列】(六)
使用ctkPluginFramework插件系统构建项目实战 **
ctk github
CTK框架使用简明教程
QT——插件的创建和使用

实战

新建库项目


选择chose进入下一下页面,类型选择Qt Plugin,输入一个名称

新建如下文件

首先需要一个虚接口 echointerface.h,在插件工程和要运行插件的工程中都要使用

#ifndef ECHOINTERFACE_H
#define ECHOINTERFACE_H#include <QObject>
#include <QString>//! [0]
class EchoInterface
{public:virtual ~EchoInterface() = default;virtual QString echo(const QString &message) = 0;
};QT_BEGIN_NAMESPACE#define EchoInterface_iid "org.qt-project.Qt.Examples.EchoInterface"Q_DECLARE_INTERFACE(EchoInterface, EchoInterface_iid)
QT_END_NAMESPACE//! [0]
#endif

Q_DECLARE_INTERFACE() 向 Qt 元对象系统注册一下我写的这个接口。
该宏的第一个参数是接口类的名字,第二个参数是 iid(相当于一个身份证信息,可以随便写个字符串)。

至此,我的程序给外界提供了个公共接口,并且为了 Qt 编程方便还向元对象系统注册了一下。以后所有的插件都通过这个接口来扩展 app 的功能,当然也可以写更多的接口供外界调用。

接下来是写插件,要继承这个接口
echoplugin.h


#ifndef ECHOPLUGIN_H
#define ECHOPLUGIN_H#include <QObject>
#include <QtPlugin>
#include "echointerface.h"//! [0]
class EchoPlugin : public QObject, EchoInterface
{Q_OBJECTQ_PLUGIN_METADATA(IID "org.qt-project.Qt.Examples.EchoInterface" FILE "MyQtPlugin.json")Q_INTERFACES(EchoInterface)public:QString echo(const QString &message) override;
};
//! [0]#endif

echoplugin.cpp

#include "echoplugin.h"//! [0]
QString EchoPlugin::echo(const QString &message)
{return message;
}
//! [0]

然后编译生成,我们需要
MyQtPlugin.dll MyQtPlugin.lib echointerface.h这三个文件

我们再新建一个工程 做一个界面

把刚才那三个文件复制到现在工程的目录下,把echointerface.h添加到工程里面(右键添加现有文件)

echowindow.h

#ifndef ECHOWINDOW_H
#define ECHOWINDOW_H#include <QWidget>
#include "echointerface.h"QT_BEGIN_NAMESPACE
class QString;
class QLineEdit;
class QLabel;
class QPushButton;
class QGridLayout;
namespace Ui { class echowindow; }
QT_END_NAMESPACEclass echowindow : public QWidget
{Q_OBJECTpublic:echowindow();~echowindow();private slots:void sendEcho();private:void createGUI();bool loadPlugin();EchoInterface *echoInterface;QLineEdit *lineEdit;QLabel *label;QPushButton *button;QGridLayout *layout;
};
#endif // ECHOWINDOW_H

echowindow.cpp

#include "echowindow.h"
#include "ui_echowindow.h"
#include "echowindow.h"#include <QCoreApplication>
#include <QDir>
#include <QLabel>
#include <QLayout>
#include <QLineEdit>
#include <QMessageBox>
#include <QPluginLoader>
#include <QPushButton>//! [0]
echowindow::echowindow()
{createGUI();setLayout(layout);setWindowTitle("Echo Plugin Example");if (!loadPlugin()) {QMessageBox::information(this, "Error", "Could not load the plugin");lineEdit->setEnabled(false);button->setEnabled(false);}
}
//! [0]//! [1]
void echowindow::sendEcho()
{QString text = echoInterface->echo(lineEdit->text());label->setText(text);
}
//! [1]//! [2]
void echowindow::createGUI()
{lineEdit = new QLineEdit;label = new QLabel;label->setFrameStyle(QFrame::Box | QFrame::Plain);button = new QPushButton(tr("Send Message"));connect(lineEdit, &QLineEdit::editingFinished,this, &echowindow::sendEcho);connect(button, &QPushButton::clicked,this, &echowindow::sendEcho);layout = new QGridLayout;layout->addWidget(new QLabel(tr("Message:")), 0, 0);layout->addWidget(lineEdit, 0, 1);layout->addWidget(new QLabel(tr("Answer:")), 1, 0);layout->addWidget(label, 1, 1);layout->addWidget(button, 2, 1, Qt::AlignRight);layout->setSizeConstraint(QLayout::SetFixedSize);
}
//! [2]//! [3]
bool echowindow::loadPlugin()
{QDir pluginsDir(QCoreApplication::applicationDirPath());
#if defined(Q_OS_WIN)if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release")pluginsDir.cdUp();
#elif defined(Q_OS_MAC)if (pluginsDir.dirName() == "MacOS") {pluginsDir.cdUp();pluginsDir.cdUp();pluginsDir.cdUp();}
#endifpluginsDir.cd("plugins");const QStringList entries = pluginsDir.entryList(QDir::Files);for (const QString &fileName : entries) {QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));QObject *plugin = pluginLoader.instance();if (plugin) {echoInterface = qobject_cast<EchoInterface *>(plugin);if (echoInterface)return true;pluginLoader.unload();}}return false;
}echowindow::~echowindow()
{}

main.cpp

#include "echowindow.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);echowindow w;w.show();return a.exec();
}

qt 从零开始搭建插件框架相关推荐

  1. 从零开始搭建Android框架系列

    原文链接:http://www.jianshu.com/nb/3767449 开篇介绍和工程目录结构[从零开始搭建android框架系列(1)] 不容错过,最全的安卓架构合集[从零开始搭建androi ...

  2. 从零开始搭建springboot框架

    大家好,我是杨叔.每天进步一点点,关注我的微信公众号[程序员杨叔],获取更多测试开发技术知识!今天分享的内容是:从零开始搭建springboot框架 一.为什么要学习springboot? Sprin ...

  3. 从零开始搭建ABP框架(Asp .Net Boilerplate)+MySQL(v8.0.22)

    从零开始搭建ABP框架(Asp .Net Boilerplate)+MySQL(v 8.0.22) 一.总体框架介绍(传统的WebAPI) 一.总体框架介绍 注意:VS2019版本必须在16.9.4以 ...

  4. ssm框架搭建连接mysql_从零开始搭建SSM框架(Spring + Spring MVC + Mybatis)

    最近在回顾和总结一些技术,想到了把之前比较火的 SSM 框架重新搭建出来,作为一个小结,同时也希望本文章写出来能对大家有一些帮助和启发,因本人水平有限,难免可能会有一些不对之处,欢迎各位大神拍砖指教, ...

  5. 从零开始搭建uni-app框架的小程序开发环境

  6. 【一步一个脚印】从零开始搭建SSM框架-- 1.1 配置JDK

    计算机中配置JDK..IDEA中配置JDK 一.计算机中配置JDK JDK官网链接: http://www.oracle.com/technetwork/java/javase/downloads/i ...

  7. Silverlight游戏设计(Game Design):(四)从零开始搭建游戏主体框架

    思路已俨然清晰,接下来要做的是从零开始搭建游戏的主体框架.Silverlight作为RIA界的新宠儿,不仅在游戏开发方面性能优越,在企业开发领域的优异表现同样日益显著.像我们这些长期从事.NET开发的 ...

  8. 从零开始免费搭建自己的博客(一)——本地搭建hexo框架

    ​ 本文是博客搭建系列文章第一篇,其他文章链接: 从零开始免费搭建自己的博客(一)--本地搭建 Hexo 框架 从零开始免费搭建自己的博客(二)--基于 GitHub pages 建站 从零开始免费搭 ...

  9. ssm radis mysql_从零开始搭建框架SSM+Redis+Mysql(一)之摘要

    从零开始搭建框架SSM+Redis+Mysql(一)之摘要 本文章为本人实际的操作后的回忆笔记,如果有步骤错漏,希望来信307793969@qq.com或者评论指出. 本文章只体现过程,仅体现操作流程 ...

最新文章

  1. ROCK 聚类算法‏
  2. 《LeetCode力扣练习》剑指 Offer 05. 替换空格 Java
  3. 洛谷P4206 聪聪与可可
  4. set集合python_python基础-set集合
  5. HDU2106 decimal system
  6. php xcat createadmin,php xcat update升级后出错,不知怎么弄
  7. excel转html不显示图片,excel表格怎么把0显示出来/为什么在excel插入背景后预览看不到图片...
  8. vocabulary
  9. 拜托,请给我贫寒简单的生活!
  10. 解决外网下载速度过慢问题
  11. 深入解析Apache NIFI的调度策略
  12. 西瓜书学习笔记第2章(模型评估与选择)
  13. 麒麟系统打印机连接服务器,麒麟桌面操作系统集成“麒麟云打印”,可解决打印机兼容问题...
  14. 初学DSP(2)-TMS320F280049C代码探究
  15. HTML5自造字,电脑中的造字程序怎么用啊怎么造字
  16. infiniband获悉
  17. 视神经面积统计 matlab,用MATLAB定量视网膜神经节细胞
  18. PMOS和NMOS在开关应用中高侧和低侧驱动的对比
  19. Opencv简单介绍
  20. 没听过计算机竞赛,国际信奥赛中国队夺冠!我忍不住再来和大家说说“编程”...

热门文章

  1. 【STM32F767】使用RTThread和TouchGFX实现DIY数字仪表(四)——同步网络时间
  2. 银河麒麟V10操作系统(桌面版/服务器版)官网免试用申请下载链接
  3. 基于Web的系统测试方法(张友生(来自中国系统分析师/中国系统分析员))
  4. centos下tomat设置开机启动
  5. 群晖NAS用迅雷远程下载Xware 1.xxx的进程监视和掉线自动重启
  6. 自考 软件工程专业 07026 网络编程应用设计 总结
  7. “国际软件自由日”头脑风暴成果
  8. Speedtest 直装高级版 +支持多平台 —— 强悍网络速度测试工具!
  9. 计算机学数学物理方法,计算机在数学物理方法习题课中的应用
  10. 芯动科技取消 Grin 矿机销售计划 愿意出售产品完整设计方案