Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
RT-Thread一般讨论
又是一个RTGUI BUG!!
发布于 2013-01-05 17:24:07 浏览:2997
订阅该版
首先介绍下情况(版本1.1rc,论坛下载,非git)。 当我需要移动一个控件的位置的时候,操作是: rtgui_widget_hide(parent) rtgui_widget_set_rect(widget, &rect); rtgui_widget_show(parent); rtgui_widget_update_clip(parent); rtgui_widget_update(parent); 一般情况下,这是正常的,不会有错误,但是当我在main_win(也就是root_win)上显示一个窗口的时候,就会出现上面操作把当前的窗口刷掉的情况,也就是相当于当前窗口不存在(完全给覆盖掉了啊),但是实际上窗口还在的,事件还在继续。 我以为是windows的Clip给刷掉了,需要刷新于是重新改为操作root_win,接着我试着用 rtgui_widget_hide(root_win) rtgui_widget_set_rect(widget, &rect); rtgui_widget_show(root_win); rtgui_widget_update_clip(root_win); rtgui_widget_update(root_win); 发现窗口这次没有隐藏,但是窗口上的控件全给覆盖了,而且在notebook页面上的view(一个容器,绑定另外的参数来取代以前老view控件)的控件反而是在窗口上面了,也就是说窗口的控件反而成了底层,而view控件倒是成了窗口上的那种效果,但是窗口还是显示着。 这个问题不仅在这种情况,其他情况也出现,比如我现在不是在控件触发事件上创建窗口,直接另一个线程创建窗口或者发事件在GUI_APP线程上创键窗口,上面的控件也会出现这种给下面控件覆盖的情况,但窗口不会给覆盖。 一般来讲window应该一直在上面的,那包括它的控件也应该是任何时候都在最上层的,怎么能出现这种情况呢?
查看更多
7
个回答
默认排序
按发布时间排序
grissiom
2013-01-06
这家伙很懒,什么也没写!
方便提供完整的示例代码么?
xiao苦
2013-01-07
这家伙很懒,什么也没写!
倒不是不方便,而是不知道该怎么提供。 ``` while (1) { result = rt_sem_take(&GuiUpdateSem, 500); if (result == RT_EOK) { while (rt_sem_take(&GuiUpdateSem, RT_WAITING_NO) == RT_EOK); //bIsUpdate = RT_TRUE; GuiErrCom(RT_FALSE); if ((IsNumPadOpen() == RT_FALSE) && (IsDownWinOpen() == RT_FALSE)) { bIsUpdate = GuiReadViewRun(); } view = GuiGetCurViewNum(); #if 1 //控件移动功能 if ((IsNumPadOpen() == RT_FALSE) && (IsDownWinOpen() == RT_FALSE)) { Move = WidgetMoveTbl[view]; while (Move != RT_NULL) { x = CheckDateRead(Move->ShiftType, Move->XShiftAddr); y = CheckDateRead(Move->ShiftType, Move->YShiftAddr); if ((x != Move->ShiftX) || (y != Move->ShiftY)) { dx = x - Move->ShiftX; dy = y - Move->ShiftY; Move->ShiftX = x; Move->ShiftY = y; } else { dx = 0; dy = 0; } if ((dx != 0) || (dy != 0)) { if (bIsUpdateClip == RT_FALSE) { bIsUpdateClip = RT_TRUE; rtgui_widget_hide(Move->widget->parent); } rect = Move->widget->extent; rect.x1 += dx; rect.x2 += dx; rect.y1 += dy; rect.y2 += dy; rtgui_widget_set_rect(Move->widget, &rect); //Move->bIsMove = RT_TRUE; bIsUpdate = RT_FALSE; } Move = Move->next; } } #endif //控件隐藏功能 Hide = WidgetHideTbl[view]; while (Hide != RT_NULL) { //val = CheckDateRead(Hide->Type, Hide->Addr); Hide->Val = CheckDateRead(Hide->Type, Hide->Addr); if (Hide->Val == Hide->Const) { if (RTGUI_WIDGET_BHIDE(Hide->widget)) { RTGUI_WIDGET_SET_UNBHIDE(Hide->widget); RTGUI_WIDGET_UNHIDE(Hide->widget); if (bIsUpdate == RT_TRUE) { //(IsDownWinOpen() == RT_TRUE)) { rtgui_widget_update(Hide->widget); } } } else { if (!RTGUI_WIDGET_BHIDE(Hide->widget)) { bIsUpdate = RT_FALSE; RTGUI_WIDGET_SET_BHIDE(Hide->widget); rtgui_widget_hide(Hide->widget); } } Hide = Hide->next; } //控件刷新功能 Monitor = WidgetMonitorTbl[view]; if ((bIsUpdate == RT_TRUE) || (IsNumPadOpen() == RT_TRUE) || (IsDownWinOpen() == RT_TRUE)) { bUpdateWidget = RT_TRUE; } else { bUpdateWidget = RT_FALSE; } while (Monitor != RT_NULL) { Monitor->Val = CheckDateRead(Monitor->Type, Monitor->Addr); if (Monitor->Val != Monitor->GetVal(Monitor->widget)) { Monitor->SetVal(Monitor->widget, Monitor->Val, bIsUpdate); } Monitor = Monitor->next; } if (bIsUpdate == RT_FALSE) { Parent = RTGUI_WIDGET(GuiGetGurView()); if (bIsUpdateClip == RT_TRUE) { bIsUpdateClip = RT_FALSE; rtgui_widget_show(Parent); rtgui_widget_update_clip(Parent); } //if ((IsNumPadOpen() == RT_FALSE) && (IsDownWinOpen() == RT_FALSE)) { bIsUpdate = RT_TRUE; rtgui_widget_update(RTGUI_WIDGET(Parent)); } } else { //GuiUpdateComError(); //rt_kprintf("通讯出错. "); GuiErrCom(RT_TRUE); } 这个是显示窗口的时候屏蔽了的。 如果 if ((IsNumPadOpen() == RT_FALSE) && (IsDownWinOpen() == RT_FALSE)) 去掉,那也就是说不管任何怀况下都会刷新,那结果就是当出有打开窗口的时候,窗口会给刷掉,但是如果此时重新刷新下windows,还是可以正常显示的。 但是如果改成 while (1) { result = rt_sem_take(&GuiUpdateSem, 500); if (result == RT_EOK) { while (rt_sem_take(&GuiUpdateSem, RT_WAITING_NO) == RT_EOK); //bIsUpdate = RT_TRUE; GuiErrCom(RT_FALSE); if ((IsNumPadOpen() == RT_FALSE) && (IsDownWinOpen() == RT_FALSE)) { bIsUpdate = GuiReadViewRun(); } view = GuiGetCurViewNum(); #if 1 //控件移动功能 // if ((IsNumPadOpen() == RT_FALSE) && (IsDownWinOpen() == RT_FALSE)) { Move = WidgetMoveTbl[view]; while (Move != RT_NULL) { x = CheckDateRead(Move->ShiftType, Move->XShiftAddr); y = CheckDateRead(Move->ShiftType, Move->YShiftAddr); if ((x != Move->ShiftX) || (y != Move->ShiftY)) { dx = x - Move->ShiftX; dy = y - Move->ShiftY; Move->ShiftX = x; Move->ShiftY = y; } else { dx = 0; dy = 0; } if ((dx != 0) || (dy != 0)) { if (bIsUpdateClip == RT_FALSE) { bIsUpdateClip = RT_TRUE; rtgui_widget_hide(RTGUI_WIDGET(main_win)); } rect = Move->widget->extent; rect.x1 += dx; rect.x2 += dx; rect.y1 += dy; rect.y2 += dy; rtgui_widget_set_rect(Move->widget, &rect); //Move->bIsMove = RT_TRUE; bIsUpdate = RT_FALSE; } Move = Move->next; } } #endif //控件隐藏功能 Hide = WidgetHideTbl[view]; while (Hide != RT_NULL) { //val = CheckDateRead(Hide->Type, Hide->Addr); Hide->Val = CheckDateRead(Hide->Type, Hide->Addr); if (Hide->Val == Hide->Const) { if (RTGUI_WIDGET_BHIDE(Hide->widget)) { RTGUI_WIDGET_SET_UNBHIDE(Hide->widget); RTGUI_WIDGET_UNHIDE(Hide->widget); if (bIsUpdate == RT_TRUE) { //(IsDownWinOpen() == RT_TRUE)) { rtgui_widget_update(Hide->widget); } } } else { if (!RTGUI_WIDGET_BHIDE(Hide->widget)) { bIsUpdate = RT_FALSE; RTGUI_WIDGET_SET_BHIDE(Hide->widget); rtgui_widget_hide(Hide->widget); } } Hide = Hide->next; } //控件刷新功能 Monitor = WidgetMonitorTbl[view]; if ((bIsUpdate == RT_TRUE) || (IsNumPadOpen() == RT_TRUE) || (IsDownWinOpen() == RT_TRUE)) { bUpdateWidget = RT_TRUE; } else { bUpdateWidget = RT_FALSE; } while (Monitor != RT_NULL) { Monitor->Val = CheckDateRead(Monitor->Type, Monitor->Addr); if (Monitor->Val != Monitor->GetVal(Monitor->widget)) { Monitor->SetVal(Monitor->widget, Monitor->Val, bIsUpdate); } Monitor = Monitor->next; } if (bIsUpdate == RT_FALSE) { Parent = RTGUI_WIDGET(GuiGetGurView()); if (bIsUpdateClip == RT_TRUE) { bIsUpdateClip = RT_FALSE; rtgui_widget_show(RTGUI_WIDGET(main_win)); rtgui_widget_update_clip(RTGUI_WIDGET(main_win)); } //if ((IsNumPadOpen() == RT_FALSE) && (IsDownWinOpen() == RT_FALSE)) { bIsUpdate = RT_TRUE; rtgui_widget_update(RTGUI_WIDGET(main_win)); } } else { //GuiUpdateComError(); //rt_kprintf("通讯出错. "); GuiErrCom(RT_TRUE); } ``` 那么windows不会给刷掉,但是上面的控件会给下面的控件覆盖掉。
grissiom
2013-01-07
这家伙很懒,什么也没写!
嗯…… 怎么说呢…… xiao苦的示例代码看的我够苦的 ;P 如果要是正式的提交 bug report,基本都会要求提供这么几项:a,版本;b,平台(如果涉及到跨平台的软件);c,可以稳定或者大概率复现 bug 的步骤和环境。有很多 race condition 不容易复现,但是也需要提供出问题时的现场环境和尽可能完善的复现步骤。 对于示例代码来说,类似的,就相当于是提供复现步骤,提供给开发者快速建立起一个 test case 来。并且对于这种情况,代码几乎就包含了所有的执行环境,也对 debug 有很大的帮助。 所以一个好的示例代码应该是在能够复现问题的基础上,不包含用户逻辑和外部依赖,越简洁明了,代码行数越少越好。 xiao苦的函数名字起的还是不错的,但是我还是不敢判断类似 IsDownWinOpen() 这种函数和数据结构到底做了什么,对于这个 bug 会有什么影响…… RTGUI_WIDGET_BHIDE 又是什么呢?而且,这份代码在我这里肯定是编译不过去的……
xiao苦
2013-01-07
这家伙很懒,什么也没写!
- -呃,这个,那个是自己加的,你直接将hide那部分删掉,与这个现象无关的。话说我虽然不加注释(因为太赶了,所以没空加),不过应该不难看懂才对吧,我结构都一直是很清晰的说,行数也不多啊。 这部分代码是完全与硬件无关的,环境MDK 5.45,CORTEX-M3,加外,Is只做返回值,一般不会有额外处理,因为代码量比较大,所以一般我都会默认这么做 ,要不就乱套了。。 你看看需要我提供什么样的代码吧,因为实际上这些情况还真是经常发生呢。
grissiom
2013-01-08
这家伙很懒,什么也没写!
上面的代码括号是不匹配的…… LZ 想要实现什么样的功能呢? 还有需要注意的是,隐藏窗口不能使用 rtgui_widget_hide,而要使用 rtgui_win_hidden(这个 hidden 是要改掉的……),不然会出问题……
xiao苦
2013-01-12
这家伙很懒,什么也没写!
我只是实现控件重新设置优胜位置而已,但是这样的话需要整个contianer的控件先隐藏再显示 ,但是win我并没有操作隐藏,结果发现整个win都被contianer覆盖了,但是win还在那,只是图像覆盖了。
撰写答案
登录
注册新账号
关注者
0
被浏览
3k
关于作者
xiao苦
这家伙很懒,什么也没写!
提问
57
回答
244
被采纳
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
rt-thread 小内存算法源码分析
2
env中添加lvgl软件包后,keil编译包--c99错误
3
【NXP-MCXA153】 定时器驱动移植
4
GD32F450 看门狗驱动适配
5
【NXP-MCXA153】看门狗驱动移植
热门标签
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
篇文章
11
次点赞
qq1078249029
2
篇文章
2
次点赞
xnosky
2
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部