基于QT Plugin框架结构
基于QT Plugin框架结构
2009-04-24 18:56:02| 分类: 日常总结|举报件一样,是一种计算机应用程序,它和主应用程序(host application)互相交互,以提供特定的功能。应用程序支持Plugin有许多原因,一些主要原因包括:使得第三方开发者有能力扩展应用程序,以提供无法先期预料的特色;减小应用程序的大小;由于软件版权之间的不兼容性将源代码和应用程序分享。Qt Plugin 分动态插件和静态插件两种。
二:qt plugin 创建和使用方法
Qt有两种与插件有关的API。一种用来扩展Qt本身的功能,如自定义数据库驱动,图像格式,文本编解码,自定义分格,等等,称为Higher-Level API。另一种用于应用程序的功能扩展,称为Lower-Level API。前一种是建立在后一种的基础之上的。这里讨论的是后一种,即用来扩展应用程序的Lower-level API。
让应用程序支持插件扩展的步骤:
1. 定义一个接口集(只有纯虚函数的类),用来与插件交流。
2. 用宏Q_DECLARE_INTERFACE()将该接口告诉Qt元对象系统。
Q_DECLARE_INTERFACE(BrushInterface,"com.trolltech.PlugAndPaint.BrushInterface/1.0")
3. 应用程序中用QPluginLoader来装载插件。
4. 用宏qobject_cast()来确定一个插件是否实现了接口。
QObject *obj = new QTimer;
QTimer *timer = qobject_cast<QTimer *>(obj);
写一个插件的步骤:
1. 声明插件类,该类从QObject和该插件希望实现的接口继承而来。
2. 用宏Q_INTERFACES()将该接口告诉Qt元对象系统。
class BasicToolsPlugin : public QObject,
public BrushInterface,
public ShapeInterface,
public FilterInterface
{
Q_OBJECT
Q_INTERFACES(BrushInterface ShapeInterface FilterInterface)
public:
...
};
3. 用宏Q_EXPORT_PLUGIN2()导出插件。
Q_EXPORT_PLUGIN2 ( PluginName, ClassName )
4. 用适当的.pro文件构建插件。
下面的代码声明了一个接口类:
class FilterInterface
{
public:
virtual ~FilterInterface() {}
virtual QStringList filters() const = 0;
virtual QImage filterImage(const QString &filter, const QImage &p_w_picpath, QWidget* parent)=0;
};
Q_DECLARE_INTERFACE(FilterInterface, "com.trolltech.PlugAndPaint.FilterInterface/1.0")
这里是实现该接口的插件类的定义:
#include <QObject>
#include <QStringList>
#include <QImage>
#include <plugandpaint/interfaces.h>
class ExtraFiltersPlugin : public QObject, public FilterInterface
{
Q_OBJECT
Q_INTERFACES(FilterInterface)
public:
QStringList filters() const;
QImage filterImage(const QString &filter, const QImage &p_w_picpath,
QWidget *parent);
};
根据插件的类型不同,pro文件中配置上有不同。下面是pro文件分析:
TEMPLATE = lib // 声明为lib,动态和静态插件一样。
CONFIG += plugin static // 声明为plugin,带static表面为静态,否则为动态。
INCLUDEPATH += ../..
HEADERS = basictoolsplugin.h
SOURCES = basictoolsplugin.cpp
TARGET = $$qtLibraryTarget(pnp_basictools) // 指明插件的名称
DESTDIR = ../../plugandpaint/plugins
加载插件的主应用程序默认在当前目录下的plugins文件夹中寻找可用插件,如果是动态插件,则直接放在plugins文件夹中便可,如果是静态,则需要在主应用程序的main函数的开始的地方用宏:Q_IMPORT_PLUGIN(pluginname(和pro文件中声明的一致))声明需要加载的插件并在工程配置中指明插件的lib位置。
三:基于qt plugin 技术的框架结构设想
1. 愿景
由于我们目前系统功能多,模块多,缺乏系统的整体性。我们想借助Qt Plugin技术,把各个独立的功能模块实现为一个个插件,统一在主体框架中,并能根据不同地方的用户的不同需求,在主框架中加载不同的功能模块,以实现整个系统的功能集中,体现出系统的整体性。
2. plugin 接口
通过技术验证得出,目前我们采用动态插件,各个功能的插件实现定义的统一接口,具体功能放在插件界面中实现,此部分就像开发独立的应用程序,只是需要注意的是:
① 功能部分的主界面需要继承至插件界面基类:PluginWidget,插件接口中用具体的实现类指针给插件界面基类指针赋值,在加载插件的主框架中通过插件接口中定义的基类指针统一调用,利用C++动态技术动态识别具体指向的实现类。
② 插件界面类必须实现基类的虚函数:CreateActions()用于创建Action
③ 创建Action需要使用基类的方法newAction创建,在此函数中加入了保存创建的Action功能。
插件接口定义如下:
class QPluginInterface
{
public:
// 析构函数
virtual ~QPluginInterface() {}
// 插件名称
virtual QString PluginName() = 0;
// 插件显示在主框架中的图标文件路径
virtual QString PluginIconurl() = 0;
// 插件提供的对外操作接口集
virtual QList<QAction*>* Actions() = 0;
// 创建插件提供的操作方法
virtual void CreateActions()=0;
// 插件的主界面
virtual QWidget* Widget() = 0;
protected:
// 插件的主界面基类
PluginWidget *pluginWidget;
};
插件界面基类定义如下:
class PluginWidget :public QMainWindow
{
Q_OBJECT
public:
PluginWidget(QWidget*parent=0);
~PluginWidget();
QList<QAction*>* Actions();
virtual void CreateActions(){}
QAction * newAction(const QIcon &icon,const QString&text,QObject*parent);
QAction * newAction(const QString&text,QObject*parent);
void AppendAction(QAction*act);
protected:
// action链表
QList<QAction*> *m_actlist;
};
下图是一个实现案例中各类之间的关系图:
3. 插件调用
插件在主框架中动态加载,目前考虑主框架基本结构是继承至QMainWindow,工具栏上显示当前加载的插件的功能键,并留有返回键可以回退到上一级。主工作区是一个QStackWidget,保存插件的界面,并把插件序号和插件对应的界面建立映射,保存在QMap<int,QWidget>中。通过序号到QStackWidget中切换界面。
下图是把DBManager做成插件加载到主框架的运行界面:
下图是把一个简单的绘图程序做成了插件,加载到主框架的运行界面:
四:总结
目前只是通过实现两个动态插件在主框架中运行,基本算是功能性的验证,离具体实施还有很多工作需要进一步的研究,比如主框架的风格,插件的管理等等。由于本人的能力有限,可能有很多认识不够的地方,请指正。
转载于:https://blog.51cto.com/11496263/1872898
基于QT Plugin框架结构相关推荐
- dgen模拟器 linux,game_box: GameBox 是一款游戏家用机模拟器,本项目基于Qt,可在windous\mac\linux等多平台使用。...
game box 概述 GameBox是一款游戏家用机模拟器,本项目基于Qt,可在windous\mac\linux等多平台使用.由于本项目基于多种开源代码开发而成,强烈提醒注意license说明. ...
- Twain的学习记录和基于Qt的相关开源项目详解
Twain学习记录和基于Qt的开源项目详解 twpp-qml 适用于 C++11 及更高版本的便携式.仅标头 TWAIN 框架. 原项目作者使用Qtwidget基于Twain静态传输一张图片 我基于h ...
- linux qt5.7下打地鼠源程序,基于QT的打地鼠游戏
[实例简介] 基于QT的一个打地鼠游戏,采用随机数的方法,是地鼠产生随机序列,有得分界面,动画效果也不错,用C++进行编程 [实例截图] [核心代码] 打地鼠 └── 打地鼠 ├── erwei │ ...
- Qt Creator创建基于Qt Widget的应用程序
Qt Creator创建基于Qt Widget的应用程序 创建基于Qt Widget的应用程序 创建文本查找器项目 设计用户界 头文件 源文件 创建资源文件 编译并运行程序 创建基于Qt Widget ...
- 基于Qt\C++实现的网络远程控制系统
基于Qt\C++实现的网络远程控制系统 本系统在Qt平台上采用C++语言实现的网络远程控制.通过将server部署到腾讯云服务器上,利用云中转的内网穿透方式实现不同内网之间的远程控制. 该系统 ...
- windows平台下基于QT和OpenCV搭建图像处理平台
在之前的博客中,已经分别比较详细地阐述了"windows平台下基于VS和OpenCV"以及"Linux平台下基于QT和OpenCV"搭建图像处理框架,并 ...
- 嵌入式linux配置qt,基于qt的嵌入式Linux开发环境搭建
摘要:本文主要介绍在PC机上搭建基于QT的嵌入式开发环境,其中很多源文件都是开发板自带,需要相应资料的可以评论留下邮箱地址. 版本:交叉编译工具链:GCC 4.7.3 [gcc-linaro-arm ...
- qt 实现html 编辑器,基于QT的HTML编辑器的设计与实现.doc
PAGE PAGE 1 郑州大学毕业设计(论文) 题 目:基于Qt的html编辑器的设计与实现 指导教师: 职称: 学生姓名: 学号: 专 业: 院(系): 完成时间: 2012年5月10日 2012 ...
- 基于Qt的P2P局域网聊天及文件传送软件设计
基于Qt的P2P局域网聊天及文件传送软件设计 zouxy09@qq.com http://blog.csdn.net/zouxy09 这是我的<通信网络>的课程设计作业,之 ...
最新文章
- 如何使用 Arthas 定位 Spring Boot 接口超时
- java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
- 【错误记录】C 语言中通过指针操作字符串常量出错记录 ( 只有 栈内存 或 堆内存 中的数据才能通过指针修改 | 不要通过指针修改常量区的字符串 )
- 基于Proteus的计算器仿真
- 经典C语言程序100例之六
- 基于动态背包的多场景广告序列投放算法
- Spring Boot加载指定属性文件
- 03 聚类算法 - K-means聚类
- 【聚类算法】| Kmeans算法的Python实现(以西瓜数据集为例)
- Python数据分析项目实例5: 分析某餐饮企业的订单详情表数据(基于matplotlib的python数据可视化分析)
- 用Spotlight实时监控Windows Server 08
- 3D深度传感ToF技术的基本原理解析
- Android 设置应用启动动画
- 这位博主居然说“我就是看故事也要把这知识学了”
- linux 的常用命令(持续更新.....)
- 推荐一些旅途的电影,歌曲和文章
- anaconda matplotlib绘图中文乱码解决
- PHP的301,302自动跳转代码
- 餐饮门店点餐系统源码(电脑手机通用)
- 智慧养老政策建议及智慧养老发展过程中存在问题
热门文章
- 纯 Win32 SDK程序为什么每次要获取设备描述表句柄
- Win32 API 打开另一个进程
- fiddler抓包实战(5)
- 第三章:3.栈和队列 -- 栈与递归的实现
- [LintCode] Wildcard Matching
- PHP去掉诡异的BOM \ufeff JSON开头包含红点
- poj 1556 (Dijkstra + Geometry 线段相交)
- 关于Configuration.ConfigurationManager
- 损害计算机系统,哪些情况下容易导致电脑系统崩溃损坏?
- centos 6.5 安装 lamp 后mysql不能启动_CentOS 6.5系统安装配置LAMP(Apache+PHP5+MySQL)服务器环境...