ucGUI的学习小结
前言
做一个小项目时需要实现GUI及相关操作(响应按键)。用的SoC的优点是功耗低,但是受限于硬件能力,之前的SDK里并没有对GUI有很好的支持。后面对GUI的界面外观还有一定的要求,就在网上搜了一下开源GUI的相关资料。最终使用ucGUI实现了GUI操作,这里把相关的学习过程做一个简单小结,所有相关资料上传到了百度云盘(链接:http://pan.baidu.com/s/1qYvv84G 密码:1o4l)
基本流程是选择开源GUI——移植ucGUI——实现GUI元素的显示——显示单页GUI界面——显示含有嵌套关系的GUI系统——优化显示流程。
1.选择开源GUI
用的SoC不支持linux,也不是Cortex-M系列的,最后只找到了两个合适的开源GUI——zlggui和ucGUI。zlggui代码量非常小,实现的gui也十分简单,适合我这种新手入门。把代码简单过了一遍并移植了下,算是加深了LCD上显示汉字、图片的代码实现(移植过程我主要参考了http://www.openedv.com/posts/list/32830.htm内容,zlggui源码见网盘)。
2.移植ucGUI
接着就是自己最终使用的ucGUI了,我用了3.90版本,参考了STM32上移植ucGUI的流程实现了在自己项目中的移植(正点原子上有很多教学贴,我参考的是附件中《ZK_UCGUI移植解析.pdf》文件)。移植过程不算复杂,主要是提供(1)LCD初始化函数(2)LCD画点函数(3)LCD的一些参数配置(分辨率,RGB位数等)。之后使用ucGUI的函数成功显示出一串字符,移植大体完成。
3.实现GUI元素的显示
之后就是熟悉如何使用ucGUI的函数,我是一边看《ucGUI中文手册.pdf》一边用硬件来做实验验证。项目中没有要求实现动画,我就主要学习了文本显示、位图显示、按钮、窗口、抗锯齿的内容,后面也满足了开发要求。
一个GUI操作界面,一般也就包含按钮、文本、背景图等元素,项目里主要就是实现显示图片和显示字符。显示图片就使用emwin提供的图片转换工具,将图片转换为c文件,调用ucGUI接口函数即可(工具见文件夹中emwin.zip)。试验后发现在使用工具转换位图时,选中压缩选项时生成的c文件大小要小很多,不过GUI显示图片花费的时间相对长一些(需要先解压缩得到像素点数据再显示)。
显示字符方面包括汉字和非汉字,一种常用的方法是使用网友提供的小软件导入选择的字体生成对应c文件,之后调用ucGUI的显示字符函数显示即可,相关资料见《定制UCGUI使用的汉字库》文件夹。这种方法在显示字号较大的字体时锯齿明显,不太美观。之后在网上找到另一种方法,利用ucGUI的抗锯齿功能绘制字符,字符文件占用空间相对大些但是显示效果要好很多。我主要借鉴的是http://blog.sina.com.cn/s/blog_74bd70030102v8od.html,用到的工具见《FontCvtST》目录。
4.显示单页GUI界面
显示元素实现后,就是尝试显示单页GUI界面,ucGUI教程里有提供过一个“对话框”控件,控件中可以按需求摆放一些元素(包括按钮、文本、图片等)并实现对这些元素操作(按钮按下、文本切换等)的响应。不过其响应函数相对复杂。自己偷懒采用的是使用窗口管理器方式,自己构造一个针对该界面的响应函数,伪代码如下:
static void _cbWindow1(WM_MESSAGE *pMSG)
{
/*窗口1的响应函数*/
}
static void _cbWindow2(WM_MESSAGE *pMSG)
{
/*窗口2的响应函数*/
}
void gui_demo(MENU_KEY *key)
{
创建各个窗口及其界面元素(按钮、文本等),只执行一次;
switch(*key)
{
/*让窗口响应按键值实现文本切换等效果*/
WM_Invalidate(&window1);
/*根据按键值更新界面指针等*/
}
}
之后在循环任务中循环调用该函数即可实现该界面对于不同按键的响应。
5.显示含有嵌套关系的GUI系统
GUI操作界面一般不止一页,而是多页且多级的。为了实现不同界面的切换,自己使用链表将不同的GUI界面串联起来;同时为了统一循环任务中对界面GUI响应函数的调用形式,使用一个全局指针指向当前工作的界面。给出部分代码如下:
(1)定义一个结构体表示一个GUI页面
struct func_node
{
void (*p_func)(MENU_KEY *key);//上面描述的该界面的响应函数,项目中界面响应按键值来更新
void (*p_clear)(void);//销毁该界面的函数
struct func_node *pre_node;//同一级的该界面的上一个界面
struct func_node *next_node;//同一级的该界面的下一个界面
struct func_node **last_level;//上一级的界面
struct func_node **next_level;//下一级界面
}
(2)将各个界面串联起来
假如有界面A、B、C,B和C为二级界面,且都是A的下一级界面。代码实现思想如下:
struct func_node node_A, node_B, node_C;
struct func_node *pnode, *pnode_level_1, *pnode_level_2;
其中pnode始终指向要显示的界面;pnode_level_1始终指向要显示的一级界面;pnode_level_2始终指向要显示的二级界面。之后初始化各个func_node变量,并利用链表串联起来
pnode_level_1 = &node_A;
pnode_level_2 = &node_B;
pnode_level_1->next_level = &pnode_level_2;
node_B.next_node = &node_C;
node_C.pre_node = &node_B;
p_node = pnode_level_1;
(3)界面的响应函数中更新指向界面的指针
函数void (*p_func)(MENU_KEY *key)就是上一小节中定义的界面响应函数,函数中需要包含根据按键值实时修改p_node、p_node_level_1和p_node_level_2部分。目的在于使它们分别始终指向要显示的界面、要显示的一级界面和要显示的二级界面。当需要更换界面时,如下更新p_node
void (*p_func)(MENU_KEY *key)
{
switch(*key)
{
/*更新指向界面的指针p_node、p_node_level_1和p_node_level_2*/
如果需要切换到下一级菜单
p_node = (struct func_node *)*(pnode->next_level);
如果切换到上一级菜单
p_node = (struct func_node *)*(pnode->last_level);
如果切换同一级的下一页菜单
p_node = p_node->next_node;
如果切换同一级的上一页菜单
p_node = p_node->pre_node;
}
}
(4)界面响应函数的调用
在循环任务中如下执行
while(1)
{
获得按键值key;
p_node->p_func(key);
}
这样处理,每一个界面对应一个单独的界面响应函数,将复杂的响应处理封装在p_func()中;同时在循环任务中统一了调用界面响应函数的接口。
6.优化显示流程
后面感觉GUI刷新速率不够快,在网上搜到一些有关优化显示流程的资料。优化主要包括以下几个方面:
(1)优化ucGUI的画点函数,该函数是被调用的最频率的函数,因此优化效果十分显著。
(2)利用lcd控制芯片的特性优化ucGUI的划线函数
(3)利用ucGUI的窗口缓存,分配较大的内存用于缓存窗口绘制
具体我参考了文件中《ucgui液晶显示深度优化篇.pdf》文档,也上传到了云盘中。
7.其他
http://www.eepw.com.cn/article/272288.htm中介绍了ucGUI绘制GIF动画
http://bbs.armfly.com/read.php?tid=377中有很多关于ucGUI的资料,十分给力
整体来说比较偷懒地使用了ucGUI提供的功能,也满足了项目需求。
ucGUI的学习小结的更多相关文章
- flex学习小结
接触到flex一个多月了,今天做一个学习小结.如果有知识错误或者意见不同的地方.欢迎交流指教. 画外音:先说一下,我是怎么接触到flex布局的.对于正在学习的童鞋们,我建议大家没事可以逛逛网站,看看人 ...
- Python 学习小结
python 学习小结 python 简明教程 1.python 文件 #!/etc/bin/python #coding=utf-8 2.main()函数 if __name__ == '__mai ...
- react学习小结(生命周期- 实例化时期 - 存在期- 销毁时期)
react学习小结 本文是我学习react的阶段性小结,如果看官你是react资深玩家,那么还请就此打住移步他处,如果你想给一些建议和指导,那么还请轻拍~ 目前团队内对react的使用非常普遍,之 ...
- objective-c基础教程——学习小结
objective-c基础教程——学习小结 提纲: 简介 与C语言相比要注意的地方 objective-c高级特性 开发工具介绍(cocoa 工具包的功能,框架,源文件组织:XCode使用介绍) ...
- pthread多线程编程的学习小结
pthread多线程编程的学习小结 pthread 同步3种方法: 1 mutex 2 条件变量 3 读写锁:支持多个线程同时读,或者一个线程写 程序员必上的开发者服务平台 —— DevSt ...
- ExtJs学习笔记之学习小结LoginDemo
ExtJs学习小结LoginDemo 1.示例:(登录界面) <!DOCTYPE html> <html> <head> <meta charset=&quo ...
- 点滴的积累---J2SE学习小结
点滴的积累---J2SE学习小结 什么是J2SE J2SE就是Java2的标准版,主要用于桌面应用软件的编程:包括那些构成Java语言核心的类.比方:数据库连接.接口定义.输入/输出.网络编程. 学习 ...
- (转) Parameter estimation for text analysis 暨LDA学习小结
Reading Note : Parameter estimation for text analysis 暨LDA学习小结 原文:http://www.xperseverance.net/blogs ...
- dubbo学习小结
dubbo学习小结 参考: https://blog.csdn.net/paul_wei2008/article/details/19355681 https://blog.csdn.net/liwe ...
随机推荐
- 上传文件到linux服务器
可以在SecureCRT下上传 先用使用命令下载一个文件:yum install lrzsz -y 然后在跳转到要保存的目录 最后,拖拽文件到secureCRT中即可
- [c#]解决方案:需要“jquery”ScriptResourceMapping。请添加一个名为 jquery (区分大小写)的 ScriptResourceMapping。
问题详情 如下图所示(部分): 出现该错误,是因为应用程序中需要使用到jquery(现在的web应用程序哪个能离开jquery呢),而目前程序目录中并没有jquery文件,或者有jquery文件但是程 ...
- 使用PHPMailer发送带附件并支持HTML内容的邮件
PHPMailer是一个封装好的PHP邮件发送类,支持发送HTML内容的电子邮件,以及可以添加附件发送,并不像PHP本身mail()函数需要服务器环境支持,您只需要设置邮件服务器以相关信息就能实现邮件 ...
- MI & CI
目前,很多特征选择文献主要是依据对共信息的直观认识使用它,即:正值表示表型的存在使特征间依赖程度增加,是特征间存在相互作用的证据:负值表示表型的存在使特征间冗余性增加:零表示特征是相互独立的,或者说, ...
- endnote X7使用方法
网页版的endnote不能添加新模版,只能用模版库里的那些,所以转而试试离线版客户端. 1.下载安装完以后(下载地址就不给了,网上有很多),在word里可以看到顶栏有插件,如果你同时也安装了在线版本, ...
- jquery的动画函数animate()讲解一
jquery animate 动画效果使用说明 animate( params, [duration], [easing], [callback] ) 用于创建自定义动画的函数. 这个函数的关键在于指 ...
- Ubuntu 安装wireshark
参考:ubuntu下安装wireshark 依赖及相关包的安装 1.编译工具 apt-get install build-essential 2.GTK+的开发文件和GLib库(libraries) ...
- Redhat6.4下配置本地yum
一.准备工作1. Linux安装盘插入光驱 2. 挂载光驱 [root@localhost ~]# mount /dev/cdrom /mnt/ mount: block device /dev/s ...
- angular实现form验证
先上效果页面:https://lpdong.github.io/myForm-1/ 其中几个知识点 1.angularJs提供了几个新的type类型: type="password" ...
- 大咖,我能转行做UX设计师吗?
前几天,有个朋友找到我,叫我给分析下他适不适合转UX设计.他的专业是建筑设计,之所以要辞职,也就是公司破事多,老板又不看重他.看到UX设计这个行业的前景很不错,想要转行.他说的也没错, 现在的UX设计 ...