• 【STM32H7】第16章 ThreadX GUIX窗口局部刷新的实现


    最新教程下载: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软件平台使用。

    实验目的:

    1. 本章主要学习GUIX的局部刷新功能。

    实验内容:

    1. 共创建了如下几个任务,通过按下按键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窗口局部刷新的实现,推荐大家设置不同的参数看效果,熟练掌握这些函数的用法。

  • 相关阅读:
    读取XML数据出错 (十六进制值 0x00)是无效的字符 的解决办法
    随记
    CRM2011:用PublishXmlRequest发布组件
    在CRM2011表单中取消OnSave操作
    Ubuntu下Postfix配置
    .net再学习
    Error registering plugins and/or workflows
    英语语法笔记摘录
    OPENCV MFC 程序出错修改
    win7激活工具使用
  • 原文地址:https://www.cnblogs.com/armfly/p/14235627.html
Copyright © 2020-2023  润新知