qt 从零开始搭建插件框架
系统设计
搭建插件框架的好处
略
分析
至少分为以下几个模块
- 需要至少一个界面插件,用于展示界面
- 需要一些功能插件,为界面提供所需功能,例如FTP功能,网络服务,数据库等等
- 需要一个插件用于管理其他插件,插件间的通信,维护等等
- 需要一个启动程序作为入口
流程
- mainApp项目作为启动整个程序的入口,生成传统意义上的exe文件,点击它启动软件
- 启动之后,需要加载管理插件的插件项目(命名为QtPluginFramework)
- QtPluginFramework加载各个插件:包括界面插件,功能插件等等
- 界面显示,用户互动产生命令调用功能插件
- 用户退出界面,QtPluginFramework卸载各个插件
- mainApp退出
QtPluginFramework项目
分析
插件式开发的好处在于,每个人可以独立的负责某个小的模块,这个模块还可以给其他的项目组用,而且很方便添加其他功能。所以QtPluginFramework项目的作用就是
- 定义一个公共接口QtPluginInterface,所有的插件都必须实现这个接口
- 加载和卸载单个插件的功能,定义QtPlugin类
- 集中管理所有插件的功能,定义QtPluginManage类
- 插件间的通信功能,定义QtEvents类
- 最后定义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 从零开始搭建插件框架相关推荐
- 从零开始搭建Android框架系列
原文链接:http://www.jianshu.com/nb/3767449 开篇介绍和工程目录结构[从零开始搭建android框架系列(1)] 不容错过,最全的安卓架构合集[从零开始搭建androi ...
- 从零开始搭建springboot框架
大家好,我是杨叔.每天进步一点点,关注我的微信公众号[程序员杨叔],获取更多测试开发技术知识!今天分享的内容是:从零开始搭建springboot框架 一.为什么要学习springboot? Sprin ...
- 从零开始搭建ABP框架(Asp .Net Boilerplate)+MySQL(v8.0.22)
从零开始搭建ABP框架(Asp .Net Boilerplate)+MySQL(v 8.0.22) 一.总体框架介绍(传统的WebAPI) 一.总体框架介绍 注意:VS2019版本必须在16.9.4以 ...
- ssm框架搭建连接mysql_从零开始搭建SSM框架(Spring + Spring MVC + Mybatis)
最近在回顾和总结一些技术,想到了把之前比较火的 SSM 框架重新搭建出来,作为一个小结,同时也希望本文章写出来能对大家有一些帮助和启发,因本人水平有限,难免可能会有一些不对之处,欢迎各位大神拍砖指教, ...
- 从零开始搭建uni-app框架的小程序开发环境
- 【一步一个脚印】从零开始搭建SSM框架-- 1.1 配置JDK
计算机中配置JDK..IDEA中配置JDK 一.计算机中配置JDK JDK官网链接: http://www.oracle.com/technetwork/java/javase/downloads/i ...
- Silverlight游戏设计(Game Design):(四)从零开始搭建游戏主体框架
思路已俨然清晰,接下来要做的是从零开始搭建游戏的主体框架.Silverlight作为RIA界的新宠儿,不仅在游戏开发方面性能优越,在企业开发领域的优异表现同样日益显著.像我们这些长期从事.NET开发的 ...
- 从零开始免费搭建自己的博客(一)——本地搭建hexo框架
本文是博客搭建系列文章第一篇,其他文章链接: 从零开始免费搭建自己的博客(一)--本地搭建 Hexo 框架 从零开始免费搭建自己的博客(二)--基于 GitHub pages 建站 从零开始免费搭 ...
- ssm radis mysql_从零开始搭建框架SSM+Redis+Mysql(一)之摘要
从零开始搭建框架SSM+Redis+Mysql(一)之摘要 本文章为本人实际的操作后的回忆笔记,如果有步骤错漏,希望来信307793969@qq.com或者评论指出. 本文章只体现过程,仅体现操作流程 ...
最新文章
- [CSS]30种时尚的CSS网站导航条
- 人工智能基准(Benchmarking)再思考
- 使用Spring Security 资源服务器来保护Spring Cloud 微服务
- mysql主从不同步怎么恢复_mysql主从不同步时,怎么恢复
- Anaconda闪退问题
- SAP FI模块与SD、MM的接口配置
- python的django介绍_【Python基础知识】Django框架简介
- SAP CRM note的自动拷贝
- UI自动化web端框架path.py代码
- python字符串是什么_python字符串表示什么
- Dubbo消费者代理的调用
- H5脱离微信通过调起微信客户端支付
- 《Python入门到精通》函数
- 《Android Studio开发实战 从零基础到App上线(第2版)》常见问题解答
- 大数据和人工智能将成消费金融主要驱动力
- Object类的用法(二)
- excel常用公式--数据清洗类
- 异步读写之利用完成历程
- javaweb JAVA JSP球鞋销售系统购物系统ssm购物系统购物商城系统源码(ssm电子商务系统)
- 华为交换机专用堆叠电缆连线指导
热门文章
- oracle高级函数去重,傅老师课堂:Oracle高级应用之去重聚合函数
- 新书推荐——信创桌面操作系统的配置与管理(统信UOS版)
- android自动烧写工具,利用fastboot烧写Android平板镜像典型步骤举例
- caffe把数据转化为lmdb格式zxw.sh
- 奥鹏网考大学计算机基础,[南开大学(本部)]《大学计算机基础》19秋期末考核(答案参考)...
- 基于牛顿方法在直流微电网潮流研究(Matlab代码实现)
- 基于野火stm32指南者的中断函数编写过程总结
- 阿里Java面试必问:java爬虫框架使用排行
- Android高级-阿里VLayout使用和原理分析
- Centos7扩容根目录