关于基于RTGUI进行新UI开发的经历

        断断续续利用rtgui开发也有一年多时间了。这个时间对很多刚毕业出来的人来说,其实也不算多长,因为刚出校门的无非就是运气好的到大公司吃香喝辣,拿钱多、做事少,运气背的到小公司给小气老板各种蹂躏摧残,永远做不完的事跟小的可怜的薪水。。。。当然,我运气没有那么好,但是也没有坏到那种地步,只不过,没多少钱就是了。

        牢骚发完了,说说前阵子开发完准备不在添砖加瓦的2。0UI吧,这套UI其实是针对RTGUI的简单应用。虽然RTGUI确实没有什么文档资料,例程什么的也严重短缺,bug也是随着应用深入曝了不少个,但是我还是很愿意向你们保证,这是个很优秀的GUI,当然它的优秀跟UCGUI不同,它没有UCGUI那么强大的稳定性,也没有UCGUI那么好的看锯齿与alpha半透明显示效果。但是它独有的跟RTT系统线程契合,UI线程事件管理,文件系统字库支持,多格式图片支持,多窗口管理(这个功能我就不吐槽了,看应用场合来评论它好坏把),确实是很有吸引力的,想到这我突然很想吐槽UCGUI了,为什么就不会支持下文件图片,非得用转换器去转。。。。


        回归正题,我做UI的原因就是有一大帮子任务乱丢的老板,希望做一个可以不改程序来搭建界面以及通讯控制下位机的显示屏,当然,成本必须是不会很高。由于当时考虑到UCGUI对中文支持不好,我偏向了RTGUI,在它基础上滚了又滚。。。当然是因为受到的帮助非常的少,(这也是我一直以来的经历把。不过做什么,上论坛都不会有人回答我问题,包括以前STM32刚开始用,做zigbee,调试sd卡,弄sclickedit环境\以及一直rx62n到rtt。伸手党虽然多,但是国内高手应该也不少的。只不过不大愿意帮下忙而已,所以后来的我就偏向于自己解决问题,基本上很少上论坛问东西,因为知道问了也是白问。我相信很多跟我一样的菜鸟都是这么经历过来的)。。。在经过多次思考,代码推翻重整,方向定向等过程,最终挖了很多个坑之后,勉强用RTGUI0.3版搭了UI1.0,从这个时候起才真真正正的开始RTGUI的基本应用。方案其实很简单,通过编写widget的派生控件实现功能空间,比如按键,指示灯,数值输入框等等,然后将它属性定好,事件也定制好,然后再定义空间解析结构,用ascii编写,约定好结构的对应位置与对应参数,再编写一段代码去读取这些参数,然后再利用这些参数创建对应控件放到对应的view里面(0.3版本rtgui是具有view 跟workbench的),然后接着再对控件进行处理,比如整合到更新监控列表\控制链表里面,生成页面通信消息队列等。这其中涉及的组件也不多,也就是个dfs跟rtgui。驱动也不多,就是按键驱动,触摸驱动,usbhost驱动,spi flash驱动,lcd驱动。基本功能相当于简单功能的组态屏。

        当然,因为是第一版的缘故,对很多概念都没有了解透彻(实际上我有个不好的习惯,就是当走路或者静下心来的时候,就会对做过的事情进行很多反复推敲琢磨,对于这个项目,我经常走路走神到想下一步该做什么, 怎么利用资源去实现更好。。。。等等之类的想法,虽然也每一偶因此少撞过人,幸运的是从来灭有撞过汽车,这个UI也是在这么反反复复推敲的产物,但是终究不是那个领域的人, 又没有领路人,很难把握怎么才算是好),所以实用性并不强,虽然整套UI编写了两万行的代码,显示效果也不差,但是实际上为了适应老大的项目,添加了太多无谓的代码,基本上可以算是半残的了,后面勉强整到他们满意,但是个人觉得它本身已经失去了使用价值(庆幸的是最后我还是丢掉了这一整套代码,因为产品很多其它流程原因,项目进展一直都是非常缓慢的,最终只出去调了一次机就挂了o(∩_∩)o 哈哈,说明文档我也早就找不到了。)


===============================================================================================================================

      如果说第一套UI是废品,那么第二套UI就是真正意义上的一代UI,它其实不该是2.0。而是1.0。由于不懂事实的老板还想利用UI1.0成果以及那廉价硬件开发7寸触摸屏与4.3按键屏开发产品,于是征求了下我的意见,那个时候离1.0开发断点已经有哦两个月了,但是我还是知道实际情况的,虽然能用,效果不差,但是终究代码太乱了,而且实现机制很不成熟,更重要的是,用的是老版的RTGUI,核心bug已经不可能修复了,如果是要用的话,还不如重新开一套新的UI,放弃老代码,采用新的代码架构,但是采纳1.0的成果机制,并利用新的rtgui win版本,开发出稳定的新一代可用UI。于是我跟老板要了两个月时间开始2.0版本的奋斗。
      当然,由于我的坏习惯,我总能在开始控件编写之前先想好方案(除了睡觉,脑子基本都在转这个项目),然后开始编写控件,基本上一个控件从开始到可用一般三天可以搞定,然后修改了新的通信机制,自己编写MODBUS协议(代码全自写,支持RTU),通讯架构特点在于,分了三层,低层负责接收发送以及编码解码,中间层负责数据整合存储,而最上层是线程实现消息接收后下发,通信完成后通知更新线程,于是就完成了一个通讯\更新的过程,这样的结果就是能比较好的合理处理显示关系。因为一般状态不改变, 控件就没有必要刷新,状态改变就只能由通讯成功才有效,这样构成了一个比较稳定的架构。而触摸与按键事件由于有了1.0的经验,也改进成利用同一的处理函数,对可控控件独立保存一个链表,控制事件派发直接只在这个表内进行处理,这样就能够把控制事件完全由自己把握,提高自己对UI的掌控性。
        在新UI里面,我大量应用了数组结构,原因在于利用数组保存的东西,虽然有上限,但是只要把握度,内存占用其实是比较小,寻址也非常容易,也方便于利用,比如说,在新UI里面,颜色我预先开辟了颜色表格数组,然后定义一个结构读取颜色放在对应的位置,然后控件的颜色属性就不再是颜色值,而是颜色序号,这样该多个控件颜色就需要改一个地方就好了。同样的方法,我应用在了图片\view上面(新RTGUI没有VIEW,但是我自己利用container派生了一个),这样就实现了比较有序的资源管理。
 
       就这样,两个月后我出来了新一代UI,一样的控件,一样的功能,但是在新UI上面, 我实现了空间隐藏与移动功能(不同于本身的隐藏, 而是真正的隐藏,隐藏了后即使parent show了,它也不会显示出来的,移动则是位置改变了),同时利用lpc1788+sdram的优势,自己想出了镜像拷贝的方法实现了控件刷新消抖(1.0就有这个了,但是那个手动弄出来的,但是到了2.0才是真正意义上的成熟,因为我完全利用rtgui事件进行控制,完全符合逻辑,并且快速,效果很好)。
 
      当然,这个套UI后面有进行测试,没有凄惨到跟第一代UI没用就挂(事实上上个第一代UI老大拿出去第一次调机后回来说厂家界面不满意,要求操作方便,要我改老UI,我改了下,一般控件修改还好,但是现在断点快一年,很多代码我自己看不下去了,太难的地方就会修改不过来了,于是我就直接给老大上了UI2.0,直接就移植到他屏上面跑了),后续UI因为需要适应4.3触摸屏\7.0触摸屏\4.3按钮屏,所以后面又慢慢的改进了一些东西(比如说,
 1。写值读值采用的是统一的API,这样一来,不管改协议,加变量都非常的方便,事实上,画了半天改这个后,后面增加变量非常快,并且完全不需要去改UI部分,仅仅改读写接口相关函数,因此可维护性加分了;
 2。通讯协议函数从固定的modbus协议改成了指针,因此能实现挂别的协议进去,事实上我也是挂了简化的不完整台达协议上去了,协议可以实现共存,通过读取解析txt配置执行哪种协议;
 3。根据用过的别人组态屏的经验,利用编写脚本实现了逻辑转换功能呢,这意味着屏也能进行简单数值处理了,这个也许你们会觉得没什么,但是如果结合状态由值控制,值由逻辑转换功能控制,我就做过一个仪表控件由逻辑控制走数值增大过程显示,一个指针在上面转此外加上控件具有移动功能,因此实现控件自己到处跑也是很简单的。此外也不需要担心显示部分功能,在实现绘制过程中,尽量使用了同样的代码,因此代码可复用度高,基本上都具有一个背景填充功能,此外背景具有图片显示功能,我又在图片引擎里面增加了图片填充区域功能,这时候假设控件是一个png图片的小人,那么小人会在屏幕背景图上移来移去的效果应该不错,并且不存在方块马赛克的BUG。。。。
 4。增加了弹窗功能,这个弹窗是仿view的模式从windows派生出来的,因此具有windose特征的同时,能进行view相同的处理,虽然我定性控制只能显示一个窗口,但是在组态应用场合很常见的东西,我怎么也不会少掉的。/
 5。增加一类在view绘制图案\边框\字体的功能,这个功能因为不是控件,所以处理快,可以进一步美化界面,光是有图片背景有时候是不够的。
 6。修改核心利用#n组合实现多行文本显示,
 )
 
       比较欣慰的是同一套UI用在多个屏上,代码改动不会很大,移来移去基本都是几个分钟的事,整体架构可维护性高了很多, 但是有个地方很不足的就是虽然控件多了, 原来控件体系弊端就出来了, 需要判断过多的时间,影响开机速度,虽然能解决这个问题, 但是也没有办法解决,因为在可读性与速度之间选择可读性比较重要, 毕竟没有上位机,界面用手动搭建的,可读性差修改也会差很多。
 ===================================================================================================================================
       随着2.0的推进,慢慢成熟,现在准备到测试阶段,虽然出现开一个多星期后会死机的问题,但是后面会想办法解决,偶尔出现的白条问题也会解决。
 然而现在,我却开始在构想第三代UI,也就是UI3.0。
       从上面讲述,注意到一个viewdraw的东东,它的特点就是覆盖刷新。别小看这个覆盖刷新, 在很多情况下,它很好,因为我们就是要求上下有序,该覆盖就覆盖,而一般的控件覆盖存在缺陷, 就是矩形判断区域方法虽然快速简单,但是不可避免出现角落空白,当控件给图名图片覆盖的时候, 它并不能显示出覆盖掉的控件部分,而是背景部分。这样就造成了显示效果大打折扣,很多效果也就实现不了,而viewdraw的dc直接就是parent,如果parent没有控件,那么viewdraw就是全图无死角刷新了啊(好强悍的特性),而在一个想法驱使下,我想利用RTGUI显示一种界面,该界面特点就是png+背景,背景图片会改变,而png就显示在上面, 但是这样就存在一个问题, 如果背景图片要改变,按现在架构就是个状态显示控件,那上面的png控件虽然透明, 但是透的是背景,而不是它下面的控件,也就是说出来的图像百分百会是缺胳膊少腿的,那么该怎么样去实现这个效果呢?利用parent?但是parent不是状态控件?这时候我就想到了viewdraw的特性,于是彻夜难眠的我想出了UI3.0的计划:放弃widget控件架构,自己搭建简单的wid类,派生出控件,这时候的控件不再是RTGUI里面的控件,而是放在view的一个链表里面的控件,它的特点是绘制只存在于view的刷新事件里面,但是本身保存了状态位,根据状态位进行显示, 由于采用了链表,在paint事件里面能简单代码直接实现绘制完成整个流程(换句话说, 刷新就是整屏刷新了),然后依然是事件处理自己管,但是控件完全覆盖更新,同样的原理,不再使用WINDOWS,直接就再自己弄个win类出来,一样放在view的刷新事件里面进行显示,这时候会发现加入隐藏与移动功能更简单了。。。因为完全就是覆盖刷新,没有什么所谓的剪不剪切域,而且不会出钱2.0版本的未隐藏先显示问题。显示效果会好很多, 更重要的是,想做的那种效果也可以实现了。
 
       但是它有个很致命的缺点,就是当我这么处理之后会非常非常非常的占用资源与内存, 效率上会很慢,同时控件一多,那么刷新起来就跟肯定会跟什么一样。。。
       用我的话讲。。它完全就是为了开发出来测试我想要的效果能不能实现的产物,没有任何实用意义,(这从使用上来说就是一种倒退,因为2.0具有实用意义,文本快速搭建漂亮的可控界面,运行还快,而这个我开发出来就是为了好看的效果)
 
 ====================================================================================================================================
       想法虽好,但是苦逼的打工仔总是没有那么多时间的,现在手头还是压着别的项目,思路都集中到那些项目上去了, 而这个UI思路还没有想好, 特别是可扩展性与基本wid架构,以及其它必要的要素,暂时不知道什么时候能够开始,但是有个疙瘩总会去想方法挖掉的, 这就是我的性格。
   
       打工了两年多, 应该特别感谢我的老大,一个很明白事情,同时也很懂得为我们着想的人,事实上能我能撑到现在不会因为当初这难度五个星的项目出走,他的帮助是少不的, 包括后期的工作的引导\经验分享\需求妥协,让我受益很多,特别是自由度高,我个人不大喜欢给束缚,那样基本就没有了自己该有的思路了.当然,我也会感谢三个对我还算很不错的老板,虽然项目是乱丢,但是确实待我不错(除了工资-  -),特别的在于一些工控指导,话不需要很多,有时候只要一点通,我就能懂很多。。。。
 在此表示衷心感谢,同时也希望UI2.0能发挥作用,作为我对公司的报答把。(3.0可是用来玩的, 不是用来用的~~~~~~)

猜你喜欢

转载自blog.csdn.net/xuzhenglim/article/details/10292023
今日推荐