pigy0754 发表于 2013-3-20 22:34:57

现在要做一个GUI界面,一直想不出好的框架。请大家给个.....

本帖最后由 pigy0754 于 2013-3-21 12:45 编辑

东西大概如下,左边为界面显示。右边为按键,多个功能键,数字键。界面下面还有6个菜单键(未画出)。

功能大概如下:
1.按能应功能键,会进入对应的功能界面,相应的下面会出现1-6个不等的菜单。
2.菜单有些会对应数值参数,有些没有,有些会有下级菜单。按了菜单后,如果此菜单有相对应的参数,那么可以按右边的数值键输入。如果没有数值参数,按数值键无效(即界面保持不变)。
3.从下级菜单返回上层菜单时,会还原进入时的状态。如下图中第3个图到第4个图(焦点回到菜单2)

以前一直case,感觉不是办法啊。在网上找了很多界面的资料,都是在“上、下、确定、取消”四键下,采用结构体的方式。但都是讲菜单的处理的,没有说参数与菜单如何关联。而且感觉这种方式好像不适应现在界面的要求。
请问下各位在写这么界面的时候,有没有什么好的方法?

cyr_hongfeng 发表于 2013-3-21 00:08:36

这个已经是产品级别的讨论了
搬个板凳,坐等听课

zhouyan 发表于 2013-3-21 00:31:19

要做出一个好个GUI不容易,请问你是用什么样的显示屏呢?

tingbin 发表于 2013-3-21 08:00:16

裸奔的话很难做的{:mad:}

lindabell 发表于 2013-3-21 08:23:22

和我写的一个GUI有些像,给你参考一下struct PAGE
{
        const struct PAGE *pParent;
        void (*Function)(u8 key);
        const struct Item *pItem;
        const u8 ItemNum;
};
struct Item
{
        const u8 TypeAndIndex;       
        const u8 *pText;
        const struct PAGE *pChildrenPage;
};

/******************************************************************************************************/
//主菜单
//定义Item项             //显示方式&序号项目的名字    项目指向的页(Page)
const struct Item main_item[]={        0x00,        "信息",                        &SMS_Page,
                                                                0x01,        "设置",                        &Setting_Page,
                                                                0x02,        "版本",                        &Version_Page,
                                                                0x03,        "时间",                        &Time_Page,
                                                                0x04,        "状态",                        0,
                                                                0x05,        "报警",                        0,
                                                                0x06,        "飞信",                        0,
                                                                0x07,        "问答",                        0
};
//定义一个Page                      父页 该页的回调函数        该页的项          项的个数                               
const struct PAGE mainPage={0,mainPageCallBack,main_item,sizeof(main_item)/sizeof(struct Item)};
/*********************************************************************************************************/


const struct PAGE Version_Page={&mainPage,Version_CallBack,0,0};
/***************************************************************************************************************/

//定义Item项            //显示方式&序号    项目的名字      项目指向的页(Page)
const struct Item Setting_item[]={        0x10,        " 00.设0",                        0,
                                                                        0x11,        " 01.设1",                        0,
                                                                        0x12,        " 02.设2",                        0,
                                                                        0x13,        " 03.设3",                        0,
                                                                        0x14,        " 04.设4",                        0,
                                                                        0x15,        " 05.设5",                        0,
                                                                        0x16,        " 06.设6 你好",                0,
                                                                        0x17,        " 07.设7",                        0,
                                                                        0x18,        " 08.设8",                        0,
                                                                        0x19,        " 09.设9",                        0,
                                                                        0x1A,        " 10.设10",                        0
                                                                        };
const struct PAGE Setting_Page={&mainPage,Setting_CallBack,Setting_item,sizeof(Setting_item)/sizeof(struct Item)};
/***************************************************************************************************************/

const struct PAGE Time_Page={&mainPage,Time_CallBack,0,0};

/***************************************************************************************************************/
//定义Item项            //显示方式&序号    项目的名字      项目指向的页(Page)
const struct Item SMS_item[]={       
                                                                        0x10,        " 00.",                        &SMS_Text_Page,
                                                                        0x11,        " 01.",                        &SMS_Text_Page,
                                                                        0x12,        " 02.",                        &SMS_Text_Page,
                                                                        0x13,        " 03.",                        &SMS_Text_Page,
                                                                        0x14,        " 04.",                        &SMS_Text_Page,
                                                                        0x15,        " 05.",                        &SMS_Text_Page,
                                                                        0x16,        " 06.",                        &SMS_Text_Page,
                                                                        0x17,        " 07.",                        &SMS_Text_Page,
                                                                        0x18,        " 08.",                        &SMS_Text_Page,
                                                                        0x19,        " 09.",                        &SMS_Text_Page,
                                                                        0x1A,        " 10.",                        &SMS_Text_Page
                                                                        };

const struct PAGE SMS_Page={&mainPage,SMS_CallBack,SMS_item,sizeof(Setting_item)/sizeof(struct Item)};这是7Z格式的,把.zip去掉就可以正常解压了

llysc 发表于 2013-3-21 08:39:32

MARK~~~~~~~~~~~~~

zjsx133 发表于 2013-3-21 08:49:02

mark 下,结构确实要下功夫

zyw19987 发表于 2013-3-21 08:59:42

单层菜单显示的参数最多是多少?太大不适合,如果只是几十个字节可以采用我这种方法:在不同菜单层将同一内存区做不同宽度划分“用共用体能实现”
1、设立一个公用接收缓存区,和显示缓存区,这两个要分开的原因是有时候接收到数字并不是要显示到屏上的东西,所以接收后需要一个“翻译”过程,并“同步”过程;
2、采用共用体将上面的两个公用缓存区划分成不同数据结构,以实现对不同层参数显示宽度的需要;
3、进入某一层菜单时对每个菜单项目显示所需宽度指定一下,这样就能有一个通用的显示函数;
4、有了通用显示,还要解决不同菜单层的数据接收,需要针对每一层做一个接收处理函数(翻译,同步两个公用缓存区)

5、整体思路架构还是符合结构体的方式的菜单处理,仍然支持多种语言切换。

电子匠人 发表于 2013-3-21 09:00:00

留名,坐等听课

zyw19987 发表于 2013-3-21 09:05:35

typedef union
{
        u8 buff;//这个的大小就是整个共用体的大小

        //电话号码设置
        u8 PhoneNumber;

        //密码修改
        u8 Password;       //控制密码//设置密码
       
        //系统时间
        struct{
                u8 Year;               
                u8 Month;
                u8 Date;
                u8 Hour;
                u8 Min;
                u8 Sec;                           
        }Time;

}DisplayContentStruct;

zyw19987 发表于 2013-3-21 09:09:43

电话号码设置层将buff分成6份 -->六组电话号码设置      缓存区全部用完
密码修改层将buff分成3份--->三种密码    只是用了公用缓存的3*7个字节
系统时间修改层将buff作为一个结构体,划分情况由该结构体决定

hpuchenhao 发表于 2013-3-21 09:12:53

裸奔的话好像也不难用函数指针做会好点 但数据结构一定要设计好

aworker 发表于 2013-3-21 09:24:41

学习!{:smile:}

mcu_lover 发表于 2013-3-21 09:27:32

5L 8L 思路都不错。楼主可以参考借鉴下。
我现在也在做这一块的工作,不过做的是通用解决方案。还没有成形,只能放一张图片上来。

maimaige 发表于 2013-3-21 09:31:52

产品级别的GUI,听课

guxingganyue 发表于 2013-3-21 09:38:02

等高手出现

我也刚弄完一个菜单,有100个页面左右,全是用case写的。。写的很乱

hamipeter 发表于 2013-3-21 09:57:18

5楼的不错

pigy0754 发表于 2013-3-21 12:40:52

多谢大家!我现在很想知道菜单与参数到底要怎么关联起来呢?

Gorgon_Meducer 发表于 2013-3-21 14:01:07

这两天在当伴郎,没空回复,但我看了这个需求,简单说一下:
1、首先,从目前的需求来看,这个菜单结构与传统的菜单在触发方式上是不同的。
   道理很简单:原来的菜单结构中,按键与菜单项之间的关系是相对的;现在的
   结构中,在每一个菜单页面中,都有专门的按键来对应菜单项,也就是说菜单
   与按键之间的关系在局部是固定的。
2、基于以上差别,相比原来对上下左右和Enter键的操作方式,现在这个结构下更
   适合使用消息地图的机制,也就是在菜单项中,要将按键值封装进去:
typedef struct _menu_item menu_item_t;
struct _menu_item {
    uint8_t chKey;
    ...
} menu_item_t;
然后在原本按键处理的地方,用搜索消息地图的方式来决定哪个菜单被触发。
3、显示部分最好与菜单逻辑部分分开。数值的设置实际上是一个独立的任务。
    如果要编写成状态机结构,推荐 至少分成三个状态:
    a) 等待按键状态。该状态会不停的轮训有无按键输入,最好是系统里面提供
      一个按键队列,改状态轮询按键队列即可。这样的好处是,长按键和短按键
      都可以一视同仁的处理——给不同的键值即可。当获得任意按键输入时,进入
      状态b。
    b) 改状态纯属搜索当前菜单页的消息地图——就是检查当前的按键是不是有菜单
      项与之匹配。如果没有搜索到匹配项,则回到状态a)。否则,记录下对应
      菜单项的处理函数的函数指针,进入状态c。
    c)该状态专门运行对应菜单的状态机函数,当状态机运行结束时,返回状态a),
      否则将保持在当前状态。

剩下的就和普通菜单结构没有什么不同啦。
要站岗去了~回头再聊,希望对大家有帮助。

zyw19987 发表于 2013-3-21 17:41:02

本帖最后由 zyw19987 于 2013-3-21 17:43 编辑

Gorgon_Meducer 发表于 2013-3-21 14:01 static/image/common/back.gif
这两天在当伴郎,没空回复,但我看了这个需求,简单说一下:
1、首先,从目前的需求来看,这个菜单结构与传 ...

每一层都封装一个按键值这样是不错的选择,但不通用。要想在传统的菜单上面实现楼主的菜单,懒人的做法是:在菜单之上的按键信息获取后结合当前菜单索引号进行“翻译”使得符合原来菜单结构的按键值就好了,也就是原来菜单结构中的按键值并非和物理按键一一对应。这样也层次清晰,保持了原有菜单的可移植性,不同状态下按键功能是(上次)应用层决定,不是菜单决定。

zyw19987 发表于 2013-3-21 17:44:40

Gorgon_Meducer 发表于 2013-3-21 14:01 static/image/common/back.gif
这两天在当伴郎,没空回复,但我看了这个需求,简单说一下:
1、首先,从目前的需求来看,这个菜单结构与传 ...

顺便问问傻孩子老师的的书怎么样了,签名处的“工作”,还能报名吗。

Gorgon_Meducer 发表于 2013-3-21 20:58:26

zyw19987 发表于 2013-3-21 17:41 static/image/common/back.gif
每一层都封装一个按键值这样是不错的选择,但不通用。要想在传统的菜单上面实现楼主的菜单,懒人的做法是 ...

其实没啥不通用的,像它这种应用环境其实蛮多的。而且由于采用的是消息地图机制,其实反而通用,
因为可以很容易给不同界面下的不同位置的按钮(比如触摸屏幕的动态按钮)分配唯一的键值。

Gorgon_Meducer 发表于 2013-3-21 20:59:27

zyw19987 发表于 2013-3-21 17:44 static/image/common/back.gif
顺便问问傻孩子老师的的书怎么样了,签名处的“工作”,还能报名吗。

书正在写,助手一直在招聘,很多人都参加了,现在正在培训呢。

pigy0754 发表于 2013-3-21 22:46:01

{:loveliness:}这么多回复了啊!多谢大家!我得先消化消化先!

cloudxxcloud 发表于 2013-3-21 22:57:08

mark 一下

zyw19987 发表于 2013-3-22 14:42:28

Gorgon_Meducer 发表于 2013-3-21 20:59 static/image/common/back.gif
书正在写,助手一直在招聘,很多人都参加了,现在正在培训呢。

如果可以,我也报个名吧。如何参加啊?

pigy0754 发表于 2013-3-22 20:25:46

lindabell 发表于 2013-3-21 08:23 static/image/common/back.gif
和我写的一个GUI有些像,给你参考一下这是7Z格式的,把.zip去掉就可以正常解压了 ...

谢谢你的例子!我好好学习一下!

foxpro2005 发表于 2013-4-26 11:09:48

楼主可以去看看周航慈老师的本书《基于嵌入式实时操作系统的程序设计技术(第2版)》 μC/OS-II 应用的教程。里面有讲解,第15章 实际项目那一部分内容。

qlasamour 发表于 2013-7-4 00:26:35

好好学习一下!

dongfo 发表于 2013-7-6 18:03:10

学习,这个不会弄,用UCGUI可以比较方便的做出来,自己写就……
页: [1]
查看完整版本: 现在要做一个GUI界面,一直想不出好的框架。请大家给个.....