基于二叉树的多层的液晶菜单界面设计 && 资料集锦下载(t6963C、菜单界面设计
工作需要写一个菜单界面运行在240*128点阵的液晶上,有上、下、确定、返回4个按键。一、功能分析
1. 菜单需要完成的功能是:
实时显示环境A中的若干传感器值(传感器数量大于液晶可以显示的最大值时,还需要翻页功能),实时显示环境B中的若干传感器值,时间显示和设置,系统信息和帮助信息。
2. 菜单界面的布局
目前分为3种:
(1) 主菜单停留在屏幕上,下级菜单被选中后显示;
(2) 下级菜单显示时,上级菜单消失;
(3) 图形文字结合显示;
由于240*128点阵的液晶,行最多显示15个16*16汉字,列最多显示8个汉字,液晶可显示8行15列,采用布局(1),
如图示:http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_678205LOZZZZ.png
液晶界面基本布局图 (原文件名:液晶界面基本布局图.png)
3. 从功能需求上看,这是一个简单的界面,配有简单的按键操作:
(1) “上”、“下”键在“环境A传感器值”,“环境B传感器值”,“时间设置”,“系统信息”4个菜单之间切换;
(2) “确定键”进入下级(子级)菜单,这里是显示信息,设置时间等;
(3) “返回键”返回上级(父级)菜单;
(4) “确定键”进入“时间设置”菜单后,“上下键”设置时间,“确定键”在年月日时分秒间切换,“返回键”完成时间设置;
基本功能完成后,进一步完善:
(5) 对于“系统信息”和“传感器值”这种类型的菜单,对应的子菜单只是显示某些信息,没有第二级需要继续选择的菜单项,故,当“当前菜单”为此类型时,不通过“确定键”直接显示相应的信息;
(6) 当“环境A”的传感器个数>8时,需要分2页显示,此时,按“确定键”翻页;
这份界面经历了3个版本,每次都有主要参考的代码资料。(说借鉴或着抄都可以,但也有我自己的构思,尤其是最后一个版本) 之前的代码有部分和界面无关的代码注释(是和当时的项目有关)
乱
帖子还有人回复
——于是就动了更改的念头
和之前比并没有多大改进,主要是整洁了些
另外这个菜单很简单,主要适用于蓝白液晶屏之类的少量显示,复杂些的搞不出来啦 二、参考版本
第1个版本,参考的是《一个占用内存极少的菜单系统的实现》 http://goo.gl/hKBsK
作者公布了代码,但更令人钦佩的是很有耐心的写了份pdf教程,很有借鉴意义。但这个方案,菜单结构复杂增删不便,可维护性差,可移植性差。论坛上坛兄a730598 《借阿莫的宝地开源个原创的LCD菜单内核》的帖子http://goo.gl/XhWao 分析的很细致。
第2个版本,同事给的,是一个多叉树的菜单设计。
关键在于菜单结构的设计,每个菜单都是一个节点,为了在父子兄菜单间切换,这个节点信息必须包含父、子、左兄弟、右兄弟节点链接,而且必须手动建立链接关系。但由于每个菜单的下级菜单个数不同,难以用统一的数据结构描述这种关系。
如图:http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_678206TD1L5U.jpg
多叉树菜单、二叉树菜单 (原文件名:多叉树菜单、二叉树菜单.jpg)
例如:a,b是兄弟菜单;a的左右兄弟都是b,b的左右兄弟都是a,但若a,b中间增加了c,变成了3兄弟a,c,b,上述关系必须更改:a的左兄弟是b,右兄弟是C,……,这些链接关系必须手动建立,一旦有增删,必须更新。
建立上述关系后,菜单间的切换很统一很方便:“确定键”当前菜单项->子菜单,若无子,则“当前菜单->功能函数”;“返回键”当前菜单->父菜单;“上”当前菜单->左兄弟;“下”当前菜单->右兄弟。但缺点也很明显。
第3个版本,参考 彭良清《基于节点编号的通用树状菜单设计方法与实现》http://goo.gl/hKBsK
这是我在下面会要重点说的,作者给出的方法是真好呀。我先copy下作者论文中的一些话:
界面设计的流程要把按键和菜单显示作为一个整体设计协同处理;
树形菜单以2层为限,选择级数超过3级,操作不便;
菜单布局,同一系统中应保持界面的一致性;菜单子项使用频率大,置前;
一个菜单(menu)是包含多个固定条目内容(菜单项menu item),并同时在屏幕上显示或消失的矩形窗口。 三、我的总结
菜单类型不同,对按键的响应不同。比如,某些菜单“确定键”进入子菜单,其它则执行某种功能(保存啦,退出啦,时间设置啦,输入参数啦,显示某些信息啦)。尤其是当按键少的时候,按键必须具有复用功能,问题是,怎么让程序知道此时此地“确定”是进入子菜单,它时它地“确定”是执行某个特殊的功能函数。(当按键多的时候,不通过菜单选择,通过按键,直接执行某种功能函数,这个本程序没有涉及到)
为了设计一个结构、流程清晰的界面,首先分析菜单的行为,对菜单进行分类:
1st. 选择型菜单:当然就是菜单间的切换了
2nd. 功能型菜单:
i. 功能1型,执行某个操作
ii. 功能2型,允许用户输入信息或设置(如时间设置)
iii. 功能3型,单向不受控的显示窗口\菜单(系统信息、帮助信息等)
然后建立菜单信息的结构:
typedef struct menu
{
uint8 ID; /*menu的唯一标识码*/
MenuInfo item; /*结构体数组,本级menu包含的menuitem信息:显示位置,名称*/
uint8 items_num; /*本级menu的menuitem个数*/
/*和其它menu的关系,由程序完成,初始化NULL即可*/
struct menu *father, /*父辈menu*/
*son, /*长子menu*/
*obrother, /*兄menu elderbrother*/
*ybrother; /*弟menu youngerbrother*/
uint8 item_sn_cur; /*当前menuitem序号(serial number),0~(itemnum-1)*/
uint8 menu_type; /*menu类型*/
} Menu;
虽然这个二叉树的菜单设计,看上去和第2个版本多叉树类似,仍需要建立菜单节点之间的父子兄弟的关系。但这只是貌似相同,这2个有很大的区别。上一张图形象地显示了2者间的区别,更详细的见论文《基于节点编号的通用树状菜单设计方法与实现》中的图6,7。
多叉树菜单间的切换在第2个版本中有讲,它需要手动建立所有父子兄弟间的链接关系。
二叉树也需要建立这种关系,但这是通过一种ID编号规则(详见论文《基于节点》3(6))建立的,程序根据确立的ID编号规则初始化节点链接关系。显而易见的好处是,当我们需要增删节点或者改变节点位置时,只需要重新分配这个惟一的ID号即可。程序根据当前节点(菜单)的ID号,就可以寻找 到它的父子兄弟菜单,具体方法是,所有的菜单存在数组内的,通过for循环匹配ID,匹配即为当前菜单,当前菜单->父菜单,就找到了它的父菜单。
因此,本菜单的关键是,根据我们自己定义的ID编号规则,建立这样一个二叉树的菜单结构;然后,根据菜单类型,确立对按键响应的整个程序流程。
《基于节点》提出的程序流程是:
While (1)
{
键值 =获取按键值的函数( );
当前菜单 = 菜单选择函数(当前菜单,键值);
if (当前菜单 == 选择型菜单)
continue;
switch (当前菜单->ID) /* 功能型菜单代码调用 */
{
case ID_1:
功能函数 ID_1();
break;
case ID_2:
……
}
}
菜单选择函数(当前菜单, 键值)
{
swithc (键值)
{
case 上:当前菜单 = 当前菜单->兄; break;
case 下:当前菜单 = 当前菜单->弟; break;
case 确定:当前菜单 = 当前菜单->父; break;
case 返回:当前菜单 = 当前菜单->子; break;
}
return(当前菜单);
}
清晰,明了,易维护,易移植。
但是,我需要设置时间,我只有4个按键,因此,上下键必须复用,上述流程会有冲突。
我的改进是:
While (1)
{
键值 =获取按键值的函数( );
当前菜单 = 菜单界面执行函数(当前菜单,键值);
键值 = 空; /* 避免无键按下时,程序重复执行上次操作 */
}
菜单界面执行函数(当前菜单,键值)
{
switch (菜单类型 )
{
case 选择型菜单:
当前菜单 = 菜单选择函数(当前菜单,键值); break; /* 此函数和上一个流程的函数一样 */
case 功能1型(执行某个操作):
当前菜单 = 功能型菜单代码调用; break;
case 功能2型(允许用户输入信息或设置(如时间设置)):
当前菜单 = 对应的功能函数; break;
case 功能3型(单向不受控的显示窗口\菜单, 系统信息、帮助信息等):
当前菜单 = 对应的功能函数; break;
}
return (当前菜单);
}
整个框架搭好之后,需要考虑细节,这些细节很容易在上述框架中实现:
1. 屏幕刷新,有键按下时刷新界面,避免屏幕的闪烁;数据的更新通过不断写入的方式而非清屏刷新;
2. 当前菜单的维护,分析所有可能改变当前菜单的函数,通过函数参数传递和返回值的方式,尽量避免使用全局变量;
3. 通过ID编号规则初始化节点间的链接关系,必然有垃圾链接,比如,主菜单无父节点,最底层菜单无子节点,如何避免在这些地方跑飞;
4. 对于多级菜单,父子菜单切换时高亮或反显的维护问题;
5. 如何实现一.3.(5)(6)的扩展功能。 四、结束啦
上述提到的所有资料我放在了我的共享空间http://goo.gl/4N1EQ
包括 1. 主题为“多层菜单界面设计”的小论文和资料
2.我用到的液晶驱动芯片t6963C的论文和资料
3. 这个液晶多层菜单界面的代码
这是对我着手写界面(或者说开始编程生涯)5个月的一点儿总结,当然也不是每天都在写,还有其它好多的工作呢。我还是有点进步哒。
不过硬伤是明显的,编程经验少、编写代码少、数据结构和算法知识缺陷、操作系统知识匮乏到简直不懂……
这个界面只能用在简单的系统上,对于复杂的系统则难以为继。
我真心希望有人能阅读我写的代码,即使风格很糟糕,然后说点什么,这对我很有帮助。
我的共享空间里可以下载到源码。
由于深刻和直接地体会到阅读没有注释的代码的痛苦和难耐,我在自己的代码里写了挺多注释,并且努力保持注释和代码的一致性;同样的原因,我也没有直接贴上代码了事,而是分析了我写代码的思路、程序的流程,留给自己,也留给需要的人;真心认为程序的流程远比代码本身更重要。
Leekp 2011年9月21日2时0分 强帖! 拿了 mark mark 过去看看。 这个一定要顶。虽然没仔细的看,但是应该不错的。 mark MARK一下 mark 不错,以后用的到 赞一个先,思路很重要啊! 莫大会给裤子吗啊? mark 建议楼主把资料放过来~~ 总结得不错。 不错。
上述提到的所有资料我放在了我的共享空间http://goo.gl/4N1EQ
打不开。好像是浏览器不支持。 有没有图片看看。谢楼主。 上个pp瞅瞅啥样 帮楼主上传一下吧
点击此处下载 ourdev_678285UDX608.zip(文件大小:9K) (原文件名:menu_code.zip)
点击此处下载 ourdev_678286WKURD3.pdf(文件大小:197K) (原文件名:基于节点编号的通用树状菜单设计方法与实现.pdf)
点击此处下载 ourdev_678287BQ358L.pdf(文件大小:258K) (原文件名:基于节点编号的通用树状菜单设计方法与实现分析C代码.pdf)
点击此处下载 ourdev_678288F1AMI3.zip(文件大小:1.93M) (原文件名:液晶多层菜单界面设计资料.zip)
点击此处下载 ourdev_678289EXTKHQ.zip(文件大小:913K) (原文件名:液晶取模软件.zip)
点击此处下载 ourdev_678290KEVCU4.rar(文件大小:1.61M) (原文件名:一个占用内存极少的菜单系统的实现.rar) t6963c资料+论文 下载不下来,谁下了传一下吧 mark mark mark 点击此处下载 ourdev_678298OSYRSY.zip(文件大小:6.50M) (原文件名:t6963c资料+论文.zip) mark mark 一般来说,速度与资源是矛盾的,占用的内存小了速度便会变慢,这是个需要权衡的问题。 强帖MARK mark!~ 强,顶!!! MARK MARK mark 不错,给力 MARK MENU 菜单的好资料!! 一定要MARK mark 好好学习菜单程序!不错的资料 mark Mark mark 网站上不去嘛 mark mark 回复【楼主位】leekp
-----------------------------------------------------------------------
今天我也开始着手LCD菜单的编制了……希望跟你学习学习……经历很重要啊 回复【49楼】melody520
-----------------------------------------------------------------------
简单的菜单其实挺好写的,我也是在参考别人 回复【22楼】chengpiaopiao菜鸟
帮楼主上传一下吧
点击此处下载(原文件名:menu_code.zip)
点击此处下载(原文件名:基于节点编号的通用树状菜单设计方法与实现.pdf)
点击此处下载(原文件名:基于节点编号的通用树状菜单设计方法与实现分析c代码.pdf)
点击此处下载(原文件名:液晶多层菜单界面设计资料.zip)
点击此处下载(原文件名:液晶取模软件.zip)
点击此处下载(原文件名:一个占用内存极少的菜单系统的实现.rar)
-----------------------------------------------------------------------
回复【27楼】chengpiaopiao菜鸟
点击此处下载(原文件名:t6963c资料+论文.zip)
-----------------------------------------------------------------------
这位坛友挺不错呀 mark 刚好需要,谢谢楼主了!! 看上去好复杂
慢慢吸收 mark 顶一个 一个很好的二叉树应用,学习了 mark mark这个很来事 亲手写过 比直接用现成代码 体会要深刻许多 mark mark mark 留名 很不错,在折腾mini2440呢,谢谢楼主分享 很不错,在折腾mini2440呢,谢谢楼主分享 这个一定要顶。虽然没仔细的看,但是应该不错的。 狂顶 收藏,好东西 mark mark mark mark mark mark mark mark mark 思路挺好!~ 留名 Cool,楼主分析的是,我以前也做了200多页的菜单,前两种方法开始试了,后来都放弃了,改用了另一种新的方式,今天晚了,改天看 当时我分析了ucGUI的源代码,从中得到启发做出了新模式,感觉那样做出来变化性更强,适应各类不同页面 这个必须得顶 强!感谢楼主的奉献精神,赞一个! 谢谢分享的资料,学习了 强大~!~学习了 楼主厚道,很多时候我们需要的不是代码,而是思路 最近正在学习菜单,留个记号 这个需要收藏一下 必须记录一下,有时间慢慢看一下
MARK一下谢谢分享 zyw19987菜单学习 哈哈,mark一下 学习 正需要{:smile:} mark 好东东 楼主强人!顶! 不错的谢谢 顶!!最近打算玩玩!! 留步学习