基于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框架结构相关推荐

  1. dgen模拟器 linux,game_box: GameBox 是一款游戏家用机模拟器,本项目基于Qt,可在windous\mac\linux等多平台使用。...

    game box 概述 GameBox是一款游戏家用机模拟器,本项目基于Qt,可在windous\mac\linux等多平台使用.由于本项目基于多种开源代码开发而成,强烈提醒注意license说明. ...

  2. Twain的学习记录和基于Qt的相关开源项目详解

    Twain学习记录和基于Qt的开源项目详解 twpp-qml 适用于 C++11 及更高版本的便携式.仅标头 TWAIN 框架. 原项目作者使用Qtwidget基于Twain静态传输一张图片 我基于h ...

  3. linux qt5.7下打地鼠源程序,基于QT的打地鼠游戏

    [实例简介] 基于QT的一个打地鼠游戏,采用随机数的方法,是地鼠产生随机序列,有得分界面,动画效果也不错,用C++进行编程 [实例截图] [核心代码] 打地鼠 └── 打地鼠 ├── erwei │  ...

  4. Qt Creator创建基于Qt Widget的应用程序

    Qt Creator创建基于Qt Widget的应用程序 创建基于Qt Widget的应用程序 创建文本查找器项目 设计用户界 头文件 源文件 创建资源文件 编译并运行程序 创建基于Qt Widget ...

  5. 基于Qt\C++实现的网络远程控制系统

    基于Qt\C++实现的网络远程控制系统     本系统在Qt平台上采用C++语言实现的网络远程控制.通过将server部署到腾讯云服务器上,利用云中转的内网穿透方式实现不同内网之间的远程控制. 该系统 ...

  6. windows平台下基于QT和OpenCV搭建图像处理平台

        在之前的博客中,已经分别比较详细地阐述了"windows平台下基于VS和OpenCV"以及"Linux平台下基于QT和OpenCV"搭建图像处理框架,并 ...

  7. 嵌入式linux配置qt,基于qt的嵌入式Linux开发环境搭建

    摘要:本文主要介绍在PC机上搭建基于QT的嵌入式开发环境,其中很多源文件都是开发板自带,需要相应资料的可以评论留下邮箱地址. 版本:交叉编译工具链:GCC 4.7.3  [gcc-linaro-arm ...

  8. qt 实现html 编辑器,基于QT的HTML编辑器的设计与实现.doc

    PAGE PAGE 1 郑州大学毕业设计(论文) 题 目:基于Qt的html编辑器的设计与实现 指导教师: 职称: 学生姓名: 学号: 专 业: 院(系): 完成时间: 2012年5月10日 2012 ...

  9. 基于Qt的P2P局域网聊天及文件传送软件设计

    基于Qt的P2P局域网聊天及文件传送软件设计 zouxy09@qq.com http://blog.csdn.net/zouxy09         这是我的<通信网络>的课程设计作业,之 ...

最新文章

  1. 如何使用 Arthas 定位 Spring Boot 接口超时
  2. java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
  3. 【错误记录】C 语言中通过指针操作字符串常量出错记录 ( 只有 栈内存 或 堆内存 中的数据才能通过指针修改 | 不要通过指针修改常量区的字符串 )
  4. 基于Proteus的计算器仿真
  5. 经典C语言程序100例之六
  6. 基于动态背包的多场景广告序列投放算法
  7. Spring Boot加载指定属性文件
  8. 03 聚类算法 - K-means聚类
  9. 【聚类算法】| Kmeans算法的Python实现(以西瓜数据集为例)
  10. Python数据分析项目实例5: 分析某餐饮企业的订单详情表数据(基于matplotlib的python数据可视化分析)
  11. 用Spotlight实时监控Windows Server 08
  12. 3D深度传感ToF技术的基本原理解析
  13. Android 设置应用启动动画
  14. 这位博主居然说“我就是看故事也要把这知识学了”
  15. linux 的常用命令(持续更新.....)
  16. 推荐一些旅途的电影,歌曲和文章
  17. anaconda matplotlib绘图中文乱码解决
  18. PHP的301,302自动跳转代码
  19. 餐饮门店点餐系统源码(电脑手机通用)
  20. 智慧养老政策建议及智慧养老发展过程中存在问题

热门文章

  1. 纯 Win32 SDK程序为什么每次要获取设备描述表句柄
  2. Win32 API 打开另一个进程
  3. fiddler抓包实战(5)
  4. 第三章:3.栈和队列 -- 栈与递归的实现
  5. [LintCode] Wildcard Matching
  6. PHP去掉诡异的BOM \ufeff JSON开头包含红点
  7. poj 1556 (Dijkstra + Geometry 线段相交)
  8. 关于Configuration.ConfigurationManager
  9. 损害计算机系统,哪些情况下容易导致电脑系统崩溃损坏?
  10. centos 6.5 安装 lamp 后mysql不能启动_CentOS 6.5系统安装配置LAMP(Apache+PHP5+MySQL)服务器环境...