嵌入式技术论坛
直播中

李涛

7年用户 1331经验值
私信 关注
[问答]

有什么好办法能先强制window先被剪切隐藏啊

STM32调试GUI程序,发现刷屏有闪烁现象。跟踪进去发现,如果一个view 1打开了2个window,那么试图通过单击按钮隐藏Window,同时显示其他的view 2时,就会有闪烁现实(主频高的CPU察觉不到比如S3C2440,处理快嘛)。主要是因为程序先执行显示view 2,再在view 2上剪切第一个window,然后又再一次剪切第二个window.

我想有什么好办法能先强制window 先被剪切隐藏。在显示view 2啊。

也就是第一步先在view 1 剪切第一个window,然后又再剪切第二个window,最后显示view 2.

看代码,主要是rtgui_win_hiden这个函数没有马上剪切绘图,它只是发个剪切的消息给mq.

但是rtgui_view_show 确是马上绘制view的图像了。

测试代码如下,主要修改一下demo_view_window. 要看3次刷屏的慢动作,可以在STM32 LCD的画线函数里,加入延时代码

if(debug_gui_delay)
{/* 这里增加了一段延时 */
rt_uint32_t i=100000;
while(i--);
}
/*
* 程序清单:窗口演示
*
* 这个例子会先创建出一个演示用的view,当点击上面的按钮时会不同的模式创建窗口
*/
#include
#include
#include
#include
#include
#include "demo_view.h"
#include
static struct rtgui_timer *timer;
static struct rtgui_label* label;
static struct rtgui_win* msgbox = RT_NULL;
static char label_text[80];
static rt_uint8_t cnt = 5;
rtgui_win_t *win1;
rtgui_win_t *win2;
/* 获取一个递增的窗口标题 */
static char* get_win_title()
{
  static rt_uint8_t win_no = 0;
  static char win_title[16];
  rt_sprintf(win_title, "窗口 %d", ++win_no);
  return win_title;
}
/* 窗口关闭时的事件处理 */
void window_demo_close(struct rtgui_widget* widget, rtgui_event_t *even)
{
  rtgui_win_t* win;
  /* 获得最顶层控件 */
  win = RTGUI_WIN(rtgui_widget_get_toplevel(widget));
  /* 销毁窗口 */
  rtgui_win_destroy(win);
}
static rt_uint16_t delta_x = 20;
static rt_uint16_t delta_y = 40;
/* 触发正常窗口显示 */
static void demo_win_onbutton(struct rtgui_widget* widget, rtgui_event_t* event)
{
  //rtgui_win_t *win;
  rtgui_label_t *label;
  rtgui_toplevel_t *parent;
  rtgui_rect_t rect = {0, 0, 100, 80};
  rtgui_rect_t rect1 = {0, 0, 100, 80};
  parent = RTGUI_TOPLEVEL(rtgui_widget_get_toplevel(widget));
  rtgui_rect_moveto(&rect, delta_x, delta_y);
  delta_x = 110;
  delta_y = 90;
  /* 创建一个窗口 */
  win1 = rtgui_win_create(parent,
    get_win_title(), &rect, RTGUI_WIN_STYLE_DEFAULT);
  rect.x1 += 10;
  rect.x2 -= 5;
  rect.y1 += 5;
  rect.y2 = rect.y1 + 20;
  /* 添加一个文本标签 */
  label = rtgui_label_create("普通窗口1");
  rtgui_widget_set_rect(RTGUI_WIDGET(label), &rect);
  rtgui_container_add_child(RTGUI_CONTAINER(win1), RTGUI_WIDGET(label));
  /* 非模态显示窗口 */
  rtgui_win_show(win1, RT_FALSE);
  parent = RTGUI_TOPLEVEL(rtgui_widget_get_toplevel(widget));
  rtgui_rect_moveto(&rect1, delta_x, delta_y);
  /* 创建一个窗口 */
  win2 = rtgui_win_create(parent,
    get_win_title(), &rect1, RTGUI_WIN_STYLE_DEFAULT);
  rect1.y1 = rect.y2 + 80;
  rect1.y2 = rect.y1 + 20;
  /* 添加一个文本标签 */
  label = rtgui_label_create("普通窗口2");
  rtgui_widget_set_rect(RTGUI_WIDGET(label), &rect1);
  rtgui_container_add_child(RTGUI_CONTAINER(win2), RTGUI_WIDGET(label));
  /* 非模态显示窗口 */
  rtgui_win_show(win2, RT_FALSE);
}
/* 触发无标题窗口显示 */
static void demo_ntitlewin_onbutton(struct rtgui_widget* widget, rtgui_event_t* event)
{
  rtgui_win_end_modal(win1, RTGUI_MODAL_CANCEL);
  rtgui_win_hiden(win1);
  rtgui_win_end_modal(win2, RTGUI_MODAL_CANCEL);
  rtgui_win_hiden(win2);
  demo_view_next(widget,event);
}
rtgui_view_t* demo_view_window(rtgui_workbench_t* workbench)
{
  rtgui_rect_t  rect;
  rtgui_view_t* view;
  rtgui_button_t *button;
  /* 创建一个演示用的视图 */
  view = demo_view(workbench, "Window Demo");
  demo_view_get_rect(view, &rect);
  rect.x1 += 5;
  rect.x2 = rect.x1 + 100;
  rect.y1 += 5;
  rect.y2 = rect.y1 + 20;
  /* 创建按钮用于显示正常窗口 */
  button = rtgui_button_create("打开2个窗口");
  rtgui_widget_set_rect(RTGUI_WIDGET(button), &rect);
  rtgui_container_add_child(RTGUI_CONTAINER(view), RTGUI_WIDGET(button));
  /* 设置onbutton为demo_win_onbutton函数 */
  rtgui_button_set_onbutton(button, demo_win_onbutton);
  demo_view_get_rect(view, &rect);
  rect.x1 += 5;
  rect.x2 = rect.x1 + 100;
  rect.y1 += 5 + 25 + 25 + 25;
  rect.y2 = rect.y1 + 20;
  /* 创建按钮用于触发一个不包含标题的窗口 */
  button = rtgui_button_create("下一个View");
  rtgui_widget_set_rect(RTGUI_WIDGET(button), &rect);
  rtgui_container_add_child(RTGUI_CONTAINER(view), RTGUI_WIDGET(button));
  /* 设置onbutton为demo_ntitlewin_onbutton函数 */
  rtgui_button_set_onbutton(button, demo_ntitlewin_onbutton);
  return view;
}

回帖(5)

贾永世

2022-4-8 11:01:25
我先试试你的代码,
这个确实有些麻烦,因为这些动作都是连续在做的。当隐藏一个窗口时,剪切域信息还未从服务侧发回来,然后workbench有继续做下一个动作了,导致剪切域更新不及时。

或许可以考虑在做完一个动作后,让workbench主动的处理下收到的事件,然后再进行下一个动作。
举报

李涛

2022-4-8 11:02:00
改成如下即可:

static void demo_ntitlewin_onbutton(struct rtgui_widget* widget, rtgui_event_t* event)

{

struct rtgui_workbench* workbench;

struct rtgui_thread* thread;

thread = (struct rtgui_thread*) (rt_thread_self()->user_data);

workbench = RTGUI_WORKBENCH(win1->parent_toplevel);

rtgui_win_end_modal(win1, RTGUI_MODAL_CANCEL);

rtgui_win_hiden(win1);

rtgui_win_end_modal(win2, RTGUI_MODAL_CANCEL);

rtgui_win_hiden(win2);

while (thread->mq->entry > 0)

{

if (rtgui_thread_recv(event, RTGUI_EVENT_BUFFER_SIZE) == RT_EOK)

{

RTGUI_WIDGET(workbench)->event_handler(RTGUI_WIDGET(workbench), event);

}

}

demo_view_next(widget,event);

}
举报

贾永世

2022-4-8 11:02:33
这样修改法有些太底层了,是否有必要提供一个API?
举报

李涛

2022-4-8 11:02:43
感觉API有必要。这样方便控制。期待ing.....
举报

陈伟

2022-4-8 11:02:52
这种更新不同步的情况,最好是由客户端自身调用服务器提供的处理事件来处理.这样才能保证代码处理的时间是step by step,避免刷新的内容在时间上产生交叉.
举报

更多回帖

发帖
×
20
完善资料,
赚取积分