最新教程下载:http://www.armbbs.cn/forum.php?mod=viewthread&tid=98429
第16章 ThreadX GUIX窗口局部刷新的实现
本章节为大家讲解GUIX窗口的局部或全局刷新的实现。这个功能用的到地方也比较多,比如2D图形的更新,音乐频谱的更新,2D图像的更新等场合都会用到这个功能。
16.1初学者重要提示
16.2 GUIX Studio设置窗口回调
16.3 GUIX窗口更新功能的实现
16.4 实验例程设计框架
16.5实验例程
16.6 总结
16.1 初学者重要提示
1、 务必看第11章学习GUIX Studio的使用方法和第12章学习GUIX Studio生成的代码移植到硬件平台的方法。
2、 本章也要用到第15章的定时器更新功能。
3、 窗口或控件的局部更新和全局更新:
- 局部更新是通过函数gx_system_dirty_partial_add来实现。
- 全部更新是通过函数gx_system_dirty_mark来实现。
- 调用时直接在窗口事件回调函数的消息里面调用即可,通过这两个函数会触发窗口或者控件的Drawing Function函数执行。
4、 注意,本章的方法不仅适用于窗口,各种控件上也适用。
16.2 GUIX Studio设置窗口回调
GUIX Studio的设置方法与第11章一样,我们这里把控件的位置和大小做了调整,并为window窗口创建一个定时器。
新调整的界面效果如下:
16.2.1 窗口事件回调设置
下面我们为窗口控件设置一个Event Function,此功能是窗口的事件回调函数。在这个回调函数里面,大家可以处理各种事件。
这里为Event Function设置的回调函数名为_cbEventWindow0,然后就可以使用GUIX Studio生成新的代码。生成的代码移植到硬件平台的方法看第12章即可。
16.2.2 窗口绘制回调设置
下面我们为窗口设置一个Draw Function,此功能是窗口的绘制回调函数。在这个回调函数里面,大家可以实现各种2D绘制。
这里为Draw Function设置的回调函数名为_cbWindow0,然后就可以使用GUIX Studio生成新的代码。
16.3 GUIX窗口更新功能的实现
在GUIX Studio上设置好事件回调函数和绘制回调函数后,剩下就是在程序里面实现定时器更新2D绘制,这里把实现方法为大家做个说明。
16.3.1 窗口全局更新方法
窗口全局更新比较简单,调用函数gx_system_dirty_mark来标记窗口为dirty即可,这样就会触发GUIX执行绘制回调函数。
#definegx_system_dirty_mark(a) _gx_system_dirty_mark((GX_WIDGET *)a); UINT _gx_system_dirty_mark(GX_WIDGET *widget);
- 形参widget是大家要更新的窗口句柄。
16.3.2 窗口局部更新方法
窗口局部更新也比较容易实现,调用函数gx_system_dirty_partial_add来标记窗口为dirty,这样就会触发GUIX执行绘制回调函数。
#define gx_system_dirty_partial_add(a, b) _gxe_system_dirty_partial_add((GX_WIDGET *)a, b) UINT _gxe_system_dirty_partial_add(GX_WIDGET *widget, GX_RECTANGLE *dirty_area)
与全局更新不同的是局部更新可以设置想更新的区域,这样可以有效降低CPU和DMA2D的利用率。
- 第1个参数是大家要更新的窗口句柄。
- 第2个参数是要更新的区域。更新区域是GX_RECTANGLE类型结构体,此结构体定义了矩形区域。
16.3.3 窗口里界面更新框架
GUIX更新界面实现框架如下:
/* ********************************************************************************************************* * 函 数 名: _cbWindow0 * 功能说明: 窗口window的绘制回调函数 * 形 参: widget 窗口句柄 * 返 回 值: 无 ********************************************************************************************************* */ VOID _cbWindow0(GX_WINDOW *widget) { /* 2D绘制部分 */ } /* ********************************************************************************************************* * 函 数 名: _cbEventWindow * 功能说明: 窗口window的事件回调函数 * 形 参: widget 窗口句柄 * event_ptr 事件指针 * 返 回 值: 返回0表示成功 ********************************************************************************************************* */ UINT _cbEventWindow(GX_WINDOW *widget, GX_EVENT *event_ptr) { switch (event_ptr->gx_event_type) { /* 控件显示事件 */ case GX_EVENT_SHOW: /* 启动一个GUIX定时器 */ gx_system_timer_start((GX_WIDGET *)widget, GUI_ID_Timer0, 1, 10); break; /* 定时器时间溢出事件*/ case GX_EVENT_TIMER: if (event_ptr->gx_event_payload.gx_event_timer_id == GUI_ID_Timer0) { //gx_system_dirty_mark(widget); gx_system_dirty_partial_add(widget, &WinPartialDraw); } break; default: return gx_window_event_process(widget, event_ptr); } return 0; }
实现思路如下:
- 事件回调函数里面创建定时器,然后定时器消息GX_EVERNT_TIMER周期调用函数gx_system_dirty_mark或者gx_system_dirty_partial_add来触发窗口绘制回调函数的执行。
- 绘制回调函数_cbWindow0里面可以绘制各种2D效果。
16.3.4 窗口里界面更新功能实例(重要)
实例代码如下,本章教程配套例子也是用的这个代码:
GX_RECTANGLE WinPartialDraw = {10, 170, 400, 230}; /* ********************************************************************************************************* * 函 数 名: _cbWindow0 * 功能说明: 窗口window的绘制回调函数 * 形 参: widget 窗口句柄 * 返 回 值: 无 ********************************************************************************************************* */ VOID _cbWindow0(GX_WINDOW *widget) { static uint32_t i = 0; GX_RECTANGLE drawto; GX_CANVAS *mycanvas; /* 默认的窗口绘制回调函数,即默认界面效果绘制 */ gx_window_draw(widget); /* 定义一个矩形框,后续的2D绘制函数都是在这个矩形范围内绘制的 */ gx_utility_rectangle_define(&drawto, WinPartialDraw.gx_rectangle_left, WinPartialDraw.gx_rectangle_top, WinPartialDraw.gx_rectangle_right, WinPartialDraw.gx_rectangle_bottom); /* 返回窗口对应的canvas画布 */ gx_widget_canvas_get(widget, &mycanvas); /* 在指定的画布上启动绘图。此功能在内部被延迟绘图算法调用,GUIX在需要画布时自动执行更新。 但是允许应用程序绕过延期绘图算法并立即执行。 首先调用gx_canvas_drawing_inititate在画布上绘画。 然后调用所需的绘图函数,然后调用gx_canvas_drawing_complete即可。 */ gx_canvas_drawing_initiate(mycanvas, widget, &drawto); /* 设置笔刷画线的颜色值 */ gx_context_raw_line_color_set(0xffff0000); /* 设置笔刷填充的颜色值 */ gx_context_raw_fill_color_set(0xff00ff00); /* 通过GX_BRUSH_SOLID_FILL使能圆圈,矩形,多边形等绘制为填充效果 */ gx_context_brush_style_set(GX_BRUSH_SOLID_FILL); /* 设置笔刷线宽 */ gx_context_brush_width_set(1); /* 绘制圆圈 */ gx_canvas_circle_draw(50+(i++)%300, 200, 25); /* 用于强制立即绘制,注意,务必和gx_canvas_drawing_initiate成对调用 */ gx_canvas_drawing_complete(mycanvas, GX_TRUE); } /* ********************************************************************************************************* * 函 数 名: _cbEventWindow * 功能说明: 窗口window的事件回调函数 * 形 参: widget 窗口句柄 * event_ptr 事件指针 * 返 回 值: 返回0表示成功 ********************************************************************************************************* */ UINT _cbEventWindow(GX_WINDOW *widget, GX_EVENT *event_ptr) { switch (event_ptr->gx_event_type) { /* 控件显示事件 */ case GX_EVENT_SHOW: /* 启动一个GUIX定时器 */ gx_system_timer_start((GX_WIDGET *)widget, GUI_ID_Timer0, 1, 10); /* 默认事件处理 */ gx_window_event_process(widget, event_ptr); break; /* 定时器时间溢出事件*/ case GX_EVENT_TIMER: if (event_ptr->gx_event_payload.gx_event_timer_id == GUI_ID_Timer0) { //gx_system_dirty_mark(widget); gx_system_dirty_partial_add(widget, &WinPartialDraw); } break; default: return gx_window_event_process(widget, event_ptr); } return 0; }
- GX_RECTANGLE WinPartialDraw
定义要重绘的矩形区域。为了实现方便起见,绘制回调函数_cbWindow0设置的绘制区域(由函数gx_utility_rectangle_define定义)和函数gx_system_dirty_partial_add都是采用的这个区域。
- _cbWindow0
窗口的绘制回调函数,此函数里面调用的各种函数在第13章有详细说明。
- GX_EVENT_SHOW
窗口显示事件。当窗口显示时,会产生此消息,既可以附加到一个可见窗口,也可以通过函数gx_widget_show()。窗口(控件)绘制前会产生此消息。
- GX_EVENT_TIMER
定时器周期性溢出事件。
此消息里面可以调用局部刷新函数gx_system_dirty_partial_add和全局刷新函数gx_system_dirty_mark。
针对这个实例,推荐大家设置不同的参数看效果,熟练掌握这些函数的用法,这样用起GUIX也得心应手。
16.4 实验例程设计框架
本章例程的重点是GUIX窗口更新的实现,任务中专门为窗口设置了Event Function事件回调函数和Draw Function绘制回调函数。
16.5 实验例程
(注,如果是电阻屏,需要做触摸校准,校准方法看本教程附件章节A)
配套例子:
本章节配套了如下两个例子供大家移植参考:
- V7-2017_GUIX Window Update
GUIX Studio生成的代码在硬件平台实际运行的工程,含有GCC,IAR,MDK AC5和AC6四个版本工程。
- V7-2018_GUIX Studio Window Update
GUIX Studio工程模板,设计界面后,生成的文件可直接添加到MDK,IAR和GCC软件平台使用。
实验目的:
- 本章主要学习GUIX的局部刷新功能。
实验内容:
- 共创建了如下几个任务,通过按下按键K1可以通过串口打印任务堆栈使用情况
App Task Start任务 :启动任务,这里用作BSP驱动包处理。
App Task MspPro任务 :消息处理,这里用作LED闪烁。
App Task UserIF任务 :按键消息处理。
App Task GUI任务 :GUI应用任务。
App Task STAT任务 :统计任务。
App Task IDLE任务 :空闲任务。
GUIX System Thread :GUI系统任务。
System Timer Thread任务:系统定时器任务。
实验效果:
GUIX Studio的界面设计如下:
串口打印任务执行情况:
IAR,MDK AC5和AC6工程可以串口打印任务执行情况:按开发板的按键K1可以打印,波特率 115200,数据位 8,奇偶校验位无,停止位 1:
Embedded Studio(GCC)平台的串口打印是通过其调试组件SEGGER RTT做的串口打印,速度也非常快,打印效果如下:
展示里面有乱码是因为Embedded Studio不支持中文。
16.6 总结
本章节主要为大家讲解了GUIX窗口局部刷新的实现,推荐大家设置不同的参数看效果,熟练掌握这些函数的用法。