Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
RT-Thread一般讨论
[请教]关于模态窗口的问题
发布于 2013-04-18 16:08:26 浏览:7009
订阅该版
界面的布局如图所示: [attach]0[/attach] Panel1是最底层的控件,其上有一个Panel2和一个"Show"Button,Panel2可以响应RTGUI_EVENT_MOUSE_BUTTON消息进行相应的处理(通过调用rtgui_object_set_event_handler()设置了消息处理函数)。在"Show" Button的消息响应函数中,创建一个win,并创建两个button("确认"、"取消")添加到该窗口上,调用rtgui_win_show(win, RT_TRUE)显示该窗口。该模态窗口上的两个button的消息响应函数会调用rtgui_win_close()函数关闭该模态窗口。 我发现被该模态窗口覆盖的Panel2在该窗口关闭之后,会收到RTGUI_EVENT_MOUSE_BUTTON事件,而且就是关闭窗口所按的位置。按理说RTGUI_EVENT_MOUSE_BUTTON已经由win处理,其下覆盖的Panel2不应该再接收到鼠标消息。不知rtgui是怎么设计的?还是我的程序设计的不合理(例如在按钮的消息响应函数中创建并显示模态窗口是否合理)? ![layout.PNG](https://oss-club.rt-thread.org/uploads/779_af9e15c790a2a9100513b1507dcee170.png) 下载附件 [test_panel.rar](https://oss-club.rt-thread.org/uploads/779_656a568de68b5967a2371c9e68b62e2a.rar) ![log.png](https://oss-club.rt-thread.org/uploads/779_f432ed35a3503d3a494a82b292f5d7f8.png)
查看更多
19
个回答
默认排序
按发布时间排序
bernard
2013-04-18
这家伙很懒,什么也没写!
是否是不同类型的MOUSE_BUTTON事件?
softwind
2013-04-19
这家伙很懒,什么也没写!
是同样类型的RTGUI_EVENT_MOUST_BUTTON,均为RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_UP,坐标位置也一样,也就是模态窗口中按下"确定"或"取消"按钮时的位置。"确定"或"取消"的消息响应函数调用rtgui_win_close()关闭模态窗口之后,Panel2还是会收到RTGUI_EVENT_MOUST_BUTTON消息。
softwind
2013-04-19
这家伙很懒,什么也没写!
再具体一点: 该界面是在Realtouch上实现的, 1) Panel1就是Realtouch上的一个block_panel; 2) ``` layout_panel = rtgui_panel_create(RTGUI_BORDER_NONE); rtgui_widget_set_rect(RTGUI_WIDGET(layout_panel), &r1); rtgui_container_add_child(RTGUI_CONTAINER(panel), RTGUI_WIDGET(layout_panel)); rtgui_object_set_event_handler(RTGUI_OBJECT(layout_panel), layout_panel_event_handler); ``` 3) Panel2的消息处理函数 ``` rt_bool_t layout_panel_event_handler(struct rtgui_object* object, struct rtgui_event* event) { struct rtgui_panel *panel; panel = RTGUI_PANEL(object); if (event->type == RTGUI_EVENT_PAINT) { /* some painting */ } else if(event->type == RTGUI_EVENT_MOUSE_BUTTON) { rt_kprintf("layout panel <- RTGUI_EVENT_MOUSE_BUTTON "); { /* do something here */ } return RT_TRUE; } else { return rtgui_panel_event_handler(object, event); } return RT_FALSE; } ``` 4) "show" button 也在panel1上: ``` button = rtgui_button_create("show"); rtgui_button_set_onbutton(button, on_show_btn); rtgui_widget_set_rect(RTGUI_WIDGET(button), &r1); rtgui_container_add_child(RTGUI_CONTAINER(panel), RTGUI_WIDGET(button)); ``` 5) ``` static void on_show_btn(struct rtgui_object* object, struct rtgui_event* event) { /* do some processing here */ /* show the modal window */ { struct rtgui_win* win; struct rtgui_label* label; struct rtgui_button* ok_btn; struct rtgui_button* cancel_btn; struct rtgui_rect screen, rect = {0, 0, 350, 190}; struct rtgui_rect r1; rt_uint8_t* buf; rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(), &screen); rtgui_rect_moveto_align(&screen, &rect, RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL); win = rtgui_win_create(RT_NULL, "x-y-z position", &rect, RTGUI_WIN_STYLE_ONTOP | RTGUI_WIN_STYLE_DESTROY_ON_CLOSE); buf = (rt_uint8_t*)rtgui_malloc(256); rt_snprintf(buf, 256, "X = %d, Y = %d, Z = %d", x, y, z); label = rtgui_label_create(buf); RTGUI_WIDGET_TEXTALIGN(label) = RTGUI_ALIGN_CENTER; rect.x1 += 20; rect.y1 += 20; rect.x2 -= 20; rect.y2 -= 75; rtgui_widget_set_rect(RTGUI_WIDGET(label), &rect); rtgui_container_add_child(RTGUI_CONTAINER(win), RTGUI_WIDGET(label)); rtgui_widget_get_extent(RTGUI_WIDGET(win), &rect); ok_btn = rtgui_button_create("确认"); rtgui_button_set_onbutton(ok_btn, on_xyz_ok_btn); r1.x1 = rect.x1 + 50; r1.x2 = r1.x1 + 90; r1.y2 = rect.y2 - 25; r1.y1 = r1.y2 - 39; rtgui_widget_set_rect(RTGUI_WIDGET(ok_btn), &r1); rtgui_container_add_child(RTGUI_CONTAINER(win), RTGUI_WIDGET(ok_btn)); cancel_btn = rtgui_button_create("取消"); rtgui_button_set_onbutton(cancel_btn, on_xyz_cancel_btn); r1.x2 = rect.x2 - 50; r1.x1 = r1.x2 - 90; rtgui_widget_set_rect(RTGUI_WIDGET(cancel_btn), &r1); rtgui_container_add_child(RTGUI_CONTAINER(win), RTGUI_WIDGET(cancel_btn)); rtgui_win_show(win, RT_TRUE); rtgui_free(buf); } } ``` 6) "确认" "取消"按钮对应的处理函数 ``` static void on_xyz_ok_btn(struct rtgui_object* object, struct rtgui_event* event) { rtgui_win_t* win; ok_pressed = RT_TRUE; win = RTGUI_WIN(rtgui_widget_get_toplevel(RTGUI_WIDGET(object))); rtgui_win_close(win); } static void on_xyz_cancel_btn(struct rtgui_object* object, struct rtgui_event* event) { rtgui_win_t* win; ok_pressed = RT_FALSE; win = RTGUI_WIN(rtgui_widget_get_toplevel(RTGUI_WIDGET(object))); rtgui_win_close(win); } ```
xiao苦
2013-04-19
这家伙很懒,什么也没写!
报告lz的, rtgui的触摸处理是会这样的,它会把事件继续往下传,处理方法可以是在控件添加一个状态判断, 只有当按下这个控件再松开的才认定有效,执行功能,目前我就是这么做的, 当然, 也会有其他途径,看你想法.
softwind
2013-04-19
这家伙很懒,什么也没写!
>报告lz的, rtgui的触摸处理是会这样的,它会把事件继续往下传,处理方法可以是在控件添加一个状态判断, 只有当按下这个控件再松开的才认定有效,执行功能,目前我就是这么做的, 当然, 也会有其他途径,看你想法. --- 谢谢回复。 现在的问题是Panel2确实接收到了需要的鼠标消息。我想了解一下rtgui对于重叠的窗口是怎么处理的?消息会传递到所有重叠的控件?
bernard
2013-04-19
这家伙很懒,什么也没写!
如果是这样,那应该是RT-Thread GUI的一个bug,报告issue吧
xiao苦
2013-04-19
这家伙很懒,什么也没写!
>如果是这样,那应该是RT-Thread GUI的一个bug,报告issue吧 --- [s:169] 这个其实严格的说, 并不是bug,因为处理代码是有当return true的时候不继续传递的, 不过在parent之间会继续传递。实际上的应用大多数是偏向于说当这个事件处理完就该在那消失不继续传递,这只是对事件处理方式不一样而已,有的应用反而有可能会需要这样。
softwind
2013-04-22
这家伙很懒,什么也没写!
>>如果是这样,那应该是RT-Thread GUI的一个bug,报告issue吧 > >--- > > > [s:169] 这个其实严格的说, 并不是bug,因为处理代码是有当return true的时候不继续传递的, 不过在parent之间会继续传递。实际上的应用大多数是偏向于说当这个事件处理完就该在那消失不继续传递,这只是对事件处理方式不一样而已,有的应用反而有可能会需要这样。 --- 不是很明白,愿闻其详。 我按照xiao苦的提示修改了一下Panel2处理鼠标消息的方法,暂时解决了Panel2响应不需要的鼠标消息的问题。 但是我感觉还有些问题没有解决,试着加入了一些调试信息: 1) 模态窗口显示的时候,和该窗口重叠的、位于其下方的控件不会接收到MOUSE_DOWN消息,这一点没有问题; 2) 在模态窗口上按下按钮关闭该模态窗口后,MOUSE_UP消息会传递给刚才被其覆盖的控件,这一点和一般的习惯有点不符,因为该消息已经被模态窗口处理了;这个问题采用一些方法也可以避免Panel2对不需要的消息的处理。也许如xiao苦所说只是习惯的问题; 3) 在模态窗口关闭后,我感觉界面会收到多余的重绘消息,打开 RTGUI_EVENT_DEBUG调试后发现,每次在Panel2上按下鼠标,都会产生如下的消息处理过程 rtgui -- CLIP_INFO --> AppMgr win: StatusBar rtgui -- CLIP_INFO --> AppMgr win: AppMgr rtgui -- WIN_DEACTIVATE --> AppMgr win: StatusBar rtgui -- WIN_ACTIVATE --> AppMgr win: AppMgr rtgui -- PAINT --> AppMgr win: AppMgr rtgui -- MOUSE_BUTTON --> AppMgr left down win: AppMgr at (609, 120) ...... 每次在Panel2上按下鼠标,总是整个界面重绘。 如果没有执行打开/关闭模态窗口的操作,就不会出现整个界面重绘的问题。感觉模态窗口的处理好像不是很完善。因为对RTGUI整个控件的消息处理不是很熟悉,调试起来也没什么方向。
softwind
2013-04-22
这家伙很懒,什么也没写!
请教Grissom, 模态窗口的使用有什么特别的限制吗?
grissiom
2013-04-22
这家伙很懒,什么也没写!
嗯,看起来像是 bug…… 重绘的问题还不是特别明白问题在哪里……
撰写答案
登录
注册新账号
关注者
0
被浏览
7k
关于作者
softwind
这家伙很懒,什么也没写!
提问
41
回答
153
被采纳
0
关注TA
发私信
相关问题
1
有关动态模块加载的一篇论文
2
最近的调程序总结
3
晕掉了,这么久都不见layer2的踪影啊
4
继续K9ii的历程
5
[GUI相关] FreeType 2
6
[GUI相关]嵌入式系统中文输入法的设计
7
20081101 RT-Thread开发者聚会总结
8
嵌入式系统基础
9
linux2.4.19在at91rm9200 上的寄存器设置
10
[转]基于嵌入式Linux的通用触摸屏校准程序
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
env中添加lvgl软件包后,keil编译包--c99错误
2
【NXP-MCXA153】 定时器驱动移植
3
GD32F450 看门狗驱动适配
4
【NXP-MCXA153】看门狗驱动移植
5
RT-Thread Studio V2.2.9 Release Note
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
UART
WIZnet_W5500
ota在线升级
PWM
freemodbus
flash
cubemx
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
编译报错
Debug
rt_mq_消息队列_msg_queue
SFUD
keil_MDK
msh
ulog
C++_cpp
MicroPython
本月问答贡献
踩姑娘的小蘑菇
7
个答案
2
次被采纳
a1012112796
18
个答案
1
次被采纳
红枫
5
个答案
1
次被采纳
Ryan_CW
5
个答案
1
次被采纳
张世争
4
个答案
1
次被采纳
本月文章贡献
YZRD
3
篇文章
6
次点赞
catcatbing
3
篇文章
6
次点赞
lizimu
2
篇文章
10
次点赞
qq1078249029
2
篇文章
2
次点赞
xnosky
2
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部