【开源】QCPFrame插件开发框架(一)

一. 前言

       一直以来,笔者都在从事工控相关的行业,时至今日已有15年的职业历程。为了更好的将自己的经验应用于实践,同时汲取各方力量助力这一开放式的开发框架,遂将其进行开源。

       框架最初的版本是基于C#开发,应用于航空自动测试系统,即View+TPS的结构,View即一个统一的UI界面,用于选择不同的TPS测试序列包,如此以来,开发人员只需要关注测试序列逻辑及硬件设备的使用,而无需关注UI设计,因为在航空自动测试系统中,被测件是成熟机载电子设备,只需要按照手册中的测试步骤,用程序调用系统中的硬件设备编写测试序列,就可以被统一的UI调用,并对测试进行控制,生成报表。

       后来笔者又进入航天测控及军工领域,这一行业有个特点就是需求不确定,甚至需要经常添加或修改UI及功能,项目周期短更迭快,需要一个可裁剪,可重用,松耦合,可高效同步的开发框架。因此笔者在原来框架的基础上,设计了第二代基于插件的开发框架。在大中型项目开发中,的确提高了项目的开发效率,但问题也随之而来。1.框架为应对技术上的需求,接口不得已进行升级,导致向下兼容性差。2.越来越多的跨平台需求,而C#在Linux下的表现实在不咋地。因此框架仍需更新换代。

       说起来惭愧,笔者除了是一个老程序员以外,也是一个原创音乐的爱好者,虽然音乐上并无建树,但在进行音乐创作的时候,国外音频宿主软件倒是给了笔者很大的设计启发。音频宿主软件,毫无疑问就是一个框架,一个容器。用户在使用的过程中,到底会安装什么样的乐器音色库,宿主根本不关心,也不知道,它只是负责管理好他们。宿主软件就像一个舞台,而乐器音色库就像是插件,是用户后期自己搬到舞台上去得,舞台只是用于承载他们完成一场美妙得音乐会。

二. QCPFrame 介绍

      QCPFrame 全称Qt-based Common Plugin Framework。它是一个开源的基于Qt的跨平台插件开发框架,旨在提高基于PC及Linux平台下工控软件设计的通用性,重用性,高效性,可裁剪性,松耦合性。在QCPFrame中,您可以基于控制台或者服务来运行最小插件系统,也可以通过view editer(也是一个插件)来编辑带有UI的桌面程序。在QCPFrame中,一切皆插件,甚至一个函数功能,菜单项,工具栏,状态栏,dock片都可以是一个插件。插件在编辑和配置插件,这一切就像是在搭积木,使得模块开发而无需关注最终的集成。作为初版的QCPFrame,它具备以下特性:

      1. 热插拔

          即支持软件启动后动态添加或替换新的插件进来,这有助于在线升级的功能实现。

      2. 系统组件/非系统组件

          由于框架采用了Model-ViewModel的架构,一切皆插件的设计思路,那么可执行程序对于系统而言,不过是一个启动器而已,大部分功能是需要插件来实现,比如插件管理器,视图编辑器,系统设置等等,这些从前是放在主程序中的功能模块,如今也是作为一个插件被宿主统一管理。如此以来,系统的升级将意味着只需要升级插件,因为主程序基本没有什么代码。这些用于不断扩充系统功能的组件,在系统中被称之为系统组件。

扫描二维码关注公众号,回复: 11629115 查看本文章

          非系统组件用于实现二次开发时,对于业务的实现。这样把框架本身和业务分开的方式,不但提高了系统的灵活性,也可以将框架与业务解耦。

      3. 组件克隆

          在项目开发的过程中,我们经常会遇到需要很多组相同的界面及功能,可能只是这些界面及功能对应的硬件通道不同而已,之前很多人的做法就是复制代码,或者写一个类然后new出多个对象。有了组件克隆,你可以轻松通过组件管理器来克隆出一模一样的组件,他们是深拷贝实现的,因此不必考虑指针的关联性。出于安全考虑,只有非系统组件支持克隆,而系统组件的克隆不被允许。

      4. 组件排序

          组件排序功能,使开发者能够调整组件在运行时被加载的顺序,这在某些与硬件初始化相关的应用中至关重要。系统提供了"Model构造时",“View构造时”,“View第一次显示时”,“View关闭时”这四个节点的信号,系统运行至这几个节点时,会按照组件排序的顺序,依次调用组件的这些接口函数。

      5.共享内存

         框架的接口提供了丰富的共享内存类型,供插件之间同步时使用,这包含C++基本类型,链表,队列等等。

Github地址: https://github.com/Jamie-tong/QCPFrame.git

码云地址:https://gitee.com/JamieT/QCPFrame.git

三. 系统结构

                                                                         图1. QCPFrame 系统结构图

        从系统结构图来看,主要的功能在左半边,对于一个控制台程序来讲,viewmodel已经不参与运行。QCPFrame+Console即为最小插件系统,可以当作一个控制台或者服务来启动最小插件系统。

        Model由QCPFModel和Configure Model组成,QCPFModel用于扫描并连接Plugins,为Plugins提供系统级接口,而Configure Model用于存储系统配置,包括系统功能设置,组件选择与克隆,运行时排序等功能,通过序列化和反序列化可以将用户的配置永久保留,在软件启动时再装载进来。

        ViewModel有着与Model类似的结构,但它已经与QCPFrame没有直接关系,它的存在只是为了使View进行前后端分离,即当你不喜欢这个view时,可以通过ViewModel快速构建你喜欢的View,你可以使用ViewModel中的属性或方法,也可以选择不用,这取决于你自己。

四. View Editor插件

      为了直观的介绍QCPFrame,我们通过系统中一个重要的插件View Editor来介绍QCPFrame的便捷之处。

     

                                                                                    图2. 带UI界面的QCPFrame

       如上图所示,View界面主要由菜单栏,工具栏,dock窗口,状态栏组成。而view editor插件要做的工作,就是帮我们添加以上各UI元素,并通过Model与特定的功能进行绑定,这一切都是可视化的,你可以调整他们的位置。

                                                                       图3. View Editor 菜单编辑功能

       对于菜单栏来说,其实可以认为每个顶级菜单项即为一颗树。view editor在设计时,允许用户在随意添加树节点,除了顶级菜单意外,可以任意添加分隔符,通过方向键调整层级关系。每个菜单项可以设置查看权限,这在后面权限管理中会讲到。添加好树节点以后,就可以通过Map Function按钮给该菜单项挂载一个Function,你可以通过Function Viewer页面来找到你要的Function,一旦完成Function挂载,该菜单项再下一次启动后,便可以通过信号槽与组件指定的功能挂接起来。通过Load Icon按钮为该菜单项设定一个图标,该图标将一直伴随这个Action。值得一提的是这些可以挂载的Function是预先在插件工程中开发好的,随着插件的增多,对于View Editor来说,可选可编辑的Function也将更丰富。

                                                                                    图4. View Editor 工具栏及状态栏编辑功能

       对于工具栏来说,允许用户添加多个工具栏,并为指定工具栏添加Action, Action下拉框的项来自菜单编辑页面所映射过的Action,也就是说你只能先在菜单下加入该新Action,才能在工具栏里添加它。多工具栏,可以让你实现类似Word一样的复杂视图,值得一提的是,工具栏编辑模块允许你指定插件里开发好的任意widget,也就是你可以将一个自定义的widget展示到工具栏里去。Widget Viewer是一个插件widget列表查看器,你可以通过它找到你要的widget。

      系统只提供了一个状态栏,其编辑类似于工具栏,只不过没有分割符,因为Qt的状态栏会自动为每个item添加分隔符。

    

                                                                              图5. View Editor 部件选择功能

       通过widiget选择功能,你可以从已经开发好的widget列表中选择你要的,在重新启动以后,系统会将这些widget放入dockwidget容器中,系统做了Layout存储,因此当你通过拖拽,调整好需要的UI并关闭系统时,该Layout将会被保存,包括工具栏的位置及Dock,如图1所示。

       其实说到这里,本节内容不过是在讲一个插件,它只是整个系统中微小的一个模块,我的意思是说,至此我们可以把任何功能与主程序剥离,而使其成为一个易于升级的热插拔模块,插件在编辑或配置自己或者其他组件(插件要说了:我命由我不由天),这一切那个空壳的view可执行程序全然不知,它只不过是一个Shell罢了。

小结:

       本篇文章简单介绍了一下该开源项目的主旨,系统结构,设计理念及一个初步的认识,说的不对的望各位大神指点。下一篇,我会介绍框架的二次开发及接口,也会展望一下未来,指定进一步的设计目标,谢谢。

猜你喜欢

转载自blog.csdn.net/jam12315/article/details/108461027