ITPub博客

首页 > 嵌入式/内核开发 > 嵌入式/内核开发 > 《LVGL开发指南 V1.0(G4电机开发板专用)》第六章 LVGL基础知识(6.5~6.8)

《LVGL开发指南 V1.0(G4电机开发板专用)》第六章 LVGL基础知识(6.5~6.8)

原创 嵌入式/内核开发 作者:正点原子 时间:2026-05-21 10:16:50 0 删除 编辑

第六章 LVGL基础知识(6.5~6.8)


        6.5 LVGL 滚动属性

       在 LVGL 中,任何对象都是支持滚动的。如果一个对象在其父对象的区域之外,则该父对象将变为可滚动的,并且在其内部出现滚动条,如下图所示:


图6.5.1 滚动条的显示


       6.5.1 滚动的类型

       支持水平滚动和垂直滚动。


       6.5.2 滚动条模式

       默认情况下,子对象超出父对象的范围区域,则该父对象会自动开启滚动条。如果用户不想开启滚动条,则可以使用lv_obj_set_scrollbar_mode函数设置滚动条的模式,其函数原型如下所示:

void lv_obj_set_scrollbar_mode(lv_obj_t *obj, lv_scrollbar_mode_t mode);

       该函数的形参,如下表所示:



表6.5.2.1 lv_obj_set_scrollbar_mode函数形参描述


       6.5.3 滚动的事件类型

       ① LV_EVENT_SCROLL_BEGIN:滚动开始。

       ② LV_EVENT_SCROLL_END:滚动结束。

       ③ LV_EVENT_SCROLL:位置变化时触发。

       这些滚动事件可以在对象回调函数中获取,相关的使用方法在后文的LVGL事件中有介绍。


       6.5.4 设置滚动方向

       用户可以调用lv_obj_set_scroll_dir函数设置对象的滚动方向,其函数原型如下所示:

void lv_obj_set_scroll_dir(lv_obj_t *obj, lv_dir_t dir);

       该函数的形参,如下表所示:



表6.5.4.1 lv_obj_set_scroll_dir函数形参描述


       注意:这些滚动方向允许以组合的形式设置。


       6.5.5 滚动的其他特性

       1. 滚动传递:

       子对象滚动时,如果它的内容已经到达了父对象的最边缘位置,此时,子对象多余的滚动(力量)将被传递到父对象中,而父对象则会发生相应的滚动(假设允许滚动),从而形成滚动链。用户可以使用LV_OBJ_FLAG_SCROLL_CHAIN_HOR/VER标志启用和禁用滚动传递。

       2. 滚动惯性:

       当用户滚动一个对象并释放它时,LVGL 可模拟滚动的惯性动量,这就像物体被抛出并平稳地减慢滚动速度。用户可以使用LV_OBJ_FLAG_SCROLL_MOMENTUM标志启用和禁用滚动惯性。

       3. 弹性滚动:

       一般情况下,对象或部件组成部分发生滚动时,其滚动范围不能超过父对象或部件主体的区域。用户可以手动控制内容的位置,让其超出区域限制,而当用户释放内容之后,其将会以动画的形式,回弹到正常的区域范围之内。


        6.6 LVGL 动画属性

       优秀的过渡动画可以让用户的GUI变得更具高级感。在LVGL中,用户可指定动画的开始值和结束值,该动画将通过回调函数来处理。


       6.6.1 创建动画

       1. 动画创建流程

       这里结合源码给大家介绍LVGL动画的创建流程,源码如下所示:

/* ① 定义动画变量 */
lv_anim_t a;
 
/* ② 初始化一个动画 */
lv_anim_init(&a);
 
/* ③设置动画回调函数 */
lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t) lv_obj_set_x); 
/* ④ 设置动画的目标 */
lv_anim_set_var(&a, obj); 
/* ⑤ 动画长度[ms] */
lv_anim_set_time(&a, duration);
/* ⑥ 设置起始值和结束值。例如0,150 */
lv_anim_set_values(&a, start, end);
 
/* ⑦ 开始动画 */
lv_anim_start(&a);

       由上述源码可知, LVGL动画的创建流程共分为七步,如下所示:

       ① 定义一个lv_anim_t变量。

       ② 调用函数lv_anim_init初始化动画。

       ③ 调用函数lv_anim_set_exec_cb设置动画回调函数。

       ④ 调用函数lv_anim_set_var设置动画执行的目标。

       ⑤ 调用函数lv_anim_set_time设置动画时间长度。

       ⑥ 调用函数lv_anim_set_values设置起始值和结束值。

       ⑦ 调用函数lv_anim_start开始动画。

       2. 可选设置:

       在创建好动画之后,用户可以选择一些额外的配置,具体可选配置如下源码所示:

/* 可选设置 */
 
/* 启动动画前的等待时间[ms] */
lv_anim_set_delay(&a, delay);
/* 设置路径(曲线)。默认是线性的 */
lv_anim_set_path(&a, lv_anim_path_ease_in);
/* 设置一个回调函数来指示动画何时准备好(空闲) */
lv_anim_set_ready_cb(&a, ready_cb);
/* 设置一个回调函数来指示动画何时启动(延迟之后) */
lv_anim_set_start_cb(&a, start_cb);
/* 准备好后,按此持续时间倒放动画。默认为0(禁用)[ms] */
lv_anim_set_playback_time(&a, time);
/* 延迟在回放。默认为0(禁用)[ms] */
lv_anim_set_playback_delay(&a, delay);
/* 重复的数量。默认值为1。LV_ANIM_REPEAT_INFINITE用于无限重复 */
lv_anim_set_repeat_count(&a, cnt);
/* 重复前延迟。默认为0(禁用)[ms] */
lv_anim_set_repeat_delay(&a, delay);
/* True(默认):立即应用起始值,false:延迟后应用起始值。真正的开始  */
lv_anim_set_early_apply(&a, true/false);

       注意:在配置可选项之前,必须先创建动画。


       6.6.2 设置动画路径

       在LVGL中,用户可以控制动画的路径,其中最简单的就是线性变化,这意味着整个动画的过程都是以固定的步长发生变化,目前,LVGL有以下设置动画路径的函数:

       ① lv_anim_path_linear:线性动画。

       ② lv_anim_path_step:最后一步改变。

       ③ lv_anim_path_ease_in:一开始很慢。

       ④ lv_anim_path_ease_out:最后慢。

       ⑤ lv_anim_path_ease_in_out:开始和结束都很慢。

       ⑥ lv_anim_path_overshoot:超出最终值。

       ⑦ lv_anim_path_bounce:从最终值反弹一点。

       上述的动画路径设置函数通常都是以回调的形式传入lv_anim_set_path函数中,该函数原型如下所示:

static inline void lv_anim_set_path_cb(lv_anim_t *a, lv_anim_path_cb_t path_cb);

       该函数的形参,如下表所示:


表6.6.2.1 lv_anim_set_path_cb函数形参描述


       返回值:无。


       6.6.3 设置动画速度

       在LVGL中,动画速度指的是开始值到结束值所需的时间。用户需要设置动画速度,可调用lv_anim_speed_to_time函数,该函数原型如下所示:

uint32_t lv_anim_speed_to_time(uint32_t speed, int32_t start, int32_t end);

       该函数的形参,如下表所示:


表6.6.3.1 lv_anim_set_path_cb函数形参描述


       返回值:给定参数的动画所需的时间[ms]。

       在上述的函数中,动画速度以单位/秒来表示,这里的“单位”指的是某个物理量,例如:当用户让对象往 x轴偏移时,上述的“单位”指的就是像素,而入口参数speed的速度就是像素/秒。

       注意:该函数的返回值 = (结束值-起始值)/动画速度。


       6.6.4 删除动画

       如果用户在LVGL运行当中,不需要某个动画了,可使用lv_anim_del函数删除这个动画,其函数原型如下所示:

bool lv_anim_del(void *var, lv_anim_exec_xcb_t exec_cb);

       该函数的形参,如下表所示:


表6.6.4.1 lv_anim_set_path_cb函数形参描述


       返回值:true:至少删除1个动画;false:不删除动画。


       6.6.5 动画实例

       下面我们以一个简单的实例来讲解LVGL动画使用流程,示例如下:


图6.6.5.1 动画功能示例


       上图中,标签部件(ALIENTEK)从(100,10)坐标开始向左边移动,并在(0,0)坐标上停止,整个过程的时间为5000ms。示例的实现如下源码所示:

/**
  * @brief  动画回调函数
  * @param  var:对象
  * @param  v:数值
  * @retval 无
  */
static void anim_x_cb(void* var, int32_t v)
{
    lv_obj_set_x(var, v); /* 在回调函数中更新x轴的值 */
}
 
void lv_example(void)
{
    /* 第一步:创建标签 */
    lv_obj_t* lv_obj = lv_label_create(lv_scr_act());
    lv_label_set_text(lv_obj,"ALIENTEK");
    lv_obj_set_pos(lv_obj, 100, 10);
 
    /* 第二步:动画初始化 */
    lv_anim_t a;
    lv_anim_init(&a);
    /* 第三步:设置动画目标为标签对象 */
    lv_anim_set_var(&a, lv_obj);
    /* 第四步:设置动画起点和终点 */
    lv_anim_set_values(&a, 100, 0);
    /* 第五步:设置动画时间 */
    lv_anim_set_time(&a, 5000);
    /* 第六步:设置动画回调函数 */
    lv_anim_set_exec_cb(&a, anim_x_cb);
    /* 第七步:设置动画轨道 */
    lv_anim_set_path_cb(&a, lv_anim_path_overshoot);
    /* 第八步:开启动画 */
    lv_anim_start(&a);
}

       在上述代码中,动画的回调函数非常重要,它可以适时地更新x轴的像素值,这样才能实现优秀的动画效果。


       6.6.6 动画时间线

       在LVGL中,动画时间线的设置可以进一步优化动画效果,实现非线性动画。用户可以指定动画时间线的长度、开始时间、重复次数和时间快慢等属性。为了更加方便地实现非线性动画,LVGL将动画时间线分为了多个动画的集合,这样可以较为轻松地创建复杂的动画,示意图如下:


图6.6.6.1 非线性动画示意图


       接下来,我们根据上述的示意图,编写动画时间线的实例,如下源码所示:

static lv_anim_timeline_t *anim_timeline = NULL;
 
static lv_obj_t *obj1 = NULL;
 
static const lv_coord_t obj_width = 90;
static const lv_coord_t obj_height = 70;
 
/**
 * @brief       a1动画回调函数
 * @param       var:对象
 * @param       v:数值
 * @retval      无
 */
static void set_width(void* var, int32_t v)
{
    /* 设置obj1对象宽度 */
    lv_obj_set_width((lv_obj_t*)var, v);
}
 
/**
 * @brief       a2动画回调函数
 * @param       var:对象
 * @param       v:数值
 * @retval      无
 */
static void set_height(void* var, int32_t v)
{
    /* 设置obj1对象高度 */
    lv_obj_set_height((lv_obj_t*)var, v);
}
 
/**
 * @brief       创建时间线
 * @param       无
 * @retval      无
 */
static void anim_timeline_create(void)
{
    /* obj1对象增宽动画 */
    lv_anim_t a1;
    lv_anim_init(&a1);
    lv_anim_set_var(&a1, obj1);
    lv_anim_set_values(&a1, obj_width, obj_width + 10 );
    lv_anim_set_early_apply(&a1, false);
    lv_anim_set_exec_cb(&a1, (lv_anim_exec_xcb_t)set_width);
    lv_anim_set_path_cb(&a1, lv_anim_path_overshoot);
    lv_anim_set_time(&a1, 300);
 
    /* obj1对象增高动画 */
    lv_anim_t a2;
    lv_anim_init(&a2);
    lv_anim_set_var(&a2, obj1);
    lv_anim_set_values(&a2, obj_height, obj_height + 20 );
    lv_anim_set_early_apply(&a2, false);
    lv_anim_set_exec_cb(&a2, (lv_anim_exec_xcb_t)set_height);
    lv_anim_set_path_cb(&a2, lv_anim_path_ease_out);
    lv_anim_set_time(&a2, 300);
    
    /* 创建动画时间线 */
    anim_timeline = lv_anim_timeline_create();
    /* 把a1动画添加到时间线中 */
    lv_anim_timeline_add(anim_timeline, 0, &a1);
    /* 把a2动画添加到时间线中 */
    lv_anim_timeline_add(anim_timeline, 300, &a2);
}
 
/**
 * @brief       按键回调函数
 * @param       e:事件
 * @retval      无
 */
static void btn_start_event_handler(lv_event_t *e)
{
    lv_obj_t *btn = lv_event_get_target(e);
 
    if (!anim_timeline) {
        anim_timeline_create();
    }
    /* 获取按下的点击状态 */
    bool reverse = lv_obj_has_state(btn, LV_STATE_CHECKED);
    /* 支持整个动画组的向前和向后播放 */
    lv_anim_timeline_set_reverse(anim_timeline, reverse);
    /* 启动动画时间轴 */
    lv_anim_timeline_start(anim_timeline);
}
 
/**
 * @brief       LVGL入口
 * @param       无
 * @retval      无
 */
void lv_main(void)
{
    lv_obj_t *par = lv_scr_act();
    /* 创建按键部件 */
    lv_obj_t *btn_start = lv_btn_create(par);
    /* 设置回调函数 */
lv_obj_add_event_cb(btn_start, btn_start_event_handler,
                    LV_EVENT_VALUE_CHANGED, NULL);
    lv_obj_align(btn_start, LV_ALIGN_TOP_MID, -100, 20);
    /* 按键文本 */
    lv_obj_t *label_start = lv_label_create(btn_start);
    lv_label_set_text(label_start, "Start");
    lv_obj_center(label_start);
 
    /* 创建动画操作对象 */
    obj1 = lv_obj_create(par);
    lv_obj_set_size(obj1, obj_width, obj_height);
}

       上述源码的实现逻辑如下:

       ① 当按下btn_start按键时,创建a1和a2动画,这两个动画的动画时间都是300ms;

       ② 在a1和a2的动画回调函数中,分别为obj1增宽和obj1增高;

       ③ 调用lv_anim_timeline_create函数,创建动画时间线;

       ④ 调用lv_anim_timeline_add函数把a1和a2动画挂载到动画时间线上;

       ⑤ 调用lv_anim_timeline_start函数开启动画时间线。


       6.6.6.1 动画时间线相关API函数

       1. lv_anim_timeline_create函数

       创建动画时间线,其函数原型如下所示:

lv_anim_timeline_t *lv_anim_timeline_create(void);

       返回值:动画时间线指针。

       2. lv_anim_timeline_add函数

       把动画挂载到时间线上,其函数原型如下所示:

void lv_anim_timeline_add(lv_anim_timeline_t *at, uint32_t start_time, 
lv_anim_t *a);

       该函数的形参,如下表所示:


表6.6.6.1.1 lv_anim_timeline_add函数形参描述


       返回值:无。

       3. lv_anim_timeline_start函数

       开启动画时间线,其函数原型如下所示:

uint32_t lv_anim_timeline_start(lv_anim_timeline_t *at);

       该函数的形参,如下表所示:


表6.6.6.1.2 lv_anim_timeline_start函数形参描述


       返回值:活动时间。

       4. lv_anim_timeline_set_reverse函数

       设置动画时间线的播放方向,其函数原型如下所示:

void lv_anim_timeline_set_reverse(lv_anim_timeline_t *at, bool reverse);

       该函数的形参,如下表所示:


表6.6.6.1.3 lv_anim_timeline_set_reverse函数形参描述


       返回值:无。

       5. lv_anim_timeline_stop函数

       停止动画时间线,其函数原型如下所示:

void lv_anim_timeline_stop(lv_anim_timeline_t *at);

       该函数的形参,如下表所示:


表6.6.6.1.4 lv_anim_timeline_stop函数形参描述


       返回值:无。

       6. lv_anim_timeline_set_progress函数

       设置动画时间线的进度,其函数原型如下所示:

void lv_anim_timeline_set_progress(lv_anim_timeline_t *at, uint16_t progress);

       该函数的形参,如下表所示:


表6.6.6.1.5 lv_anim_timeline_set_progress函数形参描述


       返回值:无。

       7. lv_anim_timeline_get_playtime函数

       获取动画时间线的总时长,其函数原型如下所示:

uint32_t lv_anim_timeline_get_playtime(lv_anim_timeline_t *at);

       该函数的形参,如下表所示:


表6.6.6.1.6 lv_anim_timeline_get_playtime函数形参描述


       返回值:时间线的总时长。

       8. lv_anim_timeline_get_reverse函数

       获取动画时间线是否反向播放,其函数原型如下所示:

bool lv_anim_timeline_get_reverse(lv_anim_timeline_t *at);

        该函数的形参,如下表所示:


表6.6.6.1.7 lv_anim_timeline_get_reverse函数形参描述


       返回值:ture:反向播放,false:非反向播放。

       9. lv_anim_timeline_del函数

       删除动画时间线,其函数原型如下所示:

void lv_anim_timeline_del(lv_anim_timeline_t *at);

       该函数的形参,如下表所示:


表6.6.6.1.8 lv_anim_timeline_del函数形参描述


       返回值:无。


       6.6.7 动画相关API函数

       LVGL官方提供了很多动画相关的API函数,如下表所示:


表6.6.7.1 动画相关API函数描述


        6.7 LVGL 定时器

       LVGL 有一个内置的软件定时器,它构建在硬件定时器基础之上,使系统能够提供不受硬件定时器资源限制的定时服务,其实现的功能与硬件定时器也是类似的。值得注意的是,因为lv_timer_handler函数并不是准时调用的,所以导致了软件定时器有一定的误差。


       6.7.1 创建定时器

       用户可调用lv_timer_create函数或者lv_timer_create_basic函数来创建LVGL软件定时器。

       1. lv_timer_create函数

       创建一个定时器,其函数原型如下所示:

lv_timer_t *lv_timer_create(timer_cb, period_ms, user_data);

       该函数的形参,如下表所示:


表6.7.1.1函数lv_timer_create()形参描述


       返回值:定时器指针。

       当用户调用lv_timer_create函数创建定时器时,可以指定回调函数,该回调函数将被定时调用,定时器回调函数原型如下所示:

void (*lv_timer_cb_t)(lv_timer_t *);

        2. lv_timer_create_basic函数

       创建一个定时器,其函数原型如下所示:

lv_timer_t *lv_timer_create_basic(void)
{
    return lv_timer_create(NULL, DEF_PERIOD, NULL);
}

        返回值:定时器指针。

       注意:使用该函数创建LVGL定时器时,必须调用lv_timer_set_cb函数,自定义定时回调函数,默认定时周期为DEF_PERIOD。


       6.7.2 定时器配置

       1. 定时器就绪、重置

       用户可以手动设置定时器的就绪状态以及重置定时器,相关的函数如下:

       lv_timer_ready函数

       定时器已就绪,其函数原型如下所示:

void lv_timer_ready(lv_timer_t *timer);

        该函数的形参,如下表所示:


表6.7.2.1 lv_timer_ready函数形参描述


       定时器就绪后,系统将在下一次调用lv_timer_handler时运行这个定时器。

       lv_timer_reset函数

       重置定时器,其函数原型如下所示:

void  lv_timer_reset(lv_timer_t *timer);

        该函数的形参,如下表所示:


表6.7.2.2 lv_timer_reset函数形参描述


       2. 设置定时器参数

       在LVGL软件定时器的配置中,回调函数和定时周期是非常关键的,它们相关的函数如下:

       lv_timer_set_cb函数

       设置定时器的回调函数,其函数原型如下所示:

void lv_timer_set_cb(lv_timer_t *timer, lv_timer_cb_t timer_cb);

        该函数的形参,如下表所示:


表6.7.2.3 lv_timer_set_cb函数形参描述


       返回值:无。

       lv_timer_set_period函数

       设置定时周期,其函数原型如下所示:

void lv_timer_set_period(lv_timer_t *timer, uint32_t period);

        该函数的形参,如下表所示:


表6.7.2.4 lv_timer_set_period函数形参描述


       返回值:无。

       3. 重复计数

       用户可以使用lv_timer_set_repeat_count函数设置定时器重复计数的次数。当计数次数达到指定值后,计时器将自动删除。注意:当计数次数设置为-1时,以无限期地重复计数。

       lv_timer_set_repeat_count函数

       设置定时器重复计数的次数,其函数原型如下所示:

void lv_timer_set_repeat_count(lv_timer_t *timer, int32_t repeat_count );

        该函数的形参,如下表所示:


表6.7.2.5 lv_timer_set_repeat_count函数形参描述


       返回值:无。

       4. 测量空闲时间

       用户可通过lv_timer_get_idle函数获得lv_timer_handler(定时器任务)的空闲时间百分比,以此测量出LVGL的空闲时间。注意:该函数仅测量lv_timer_handler的空闲时间,而不会测量整个系统的空闲时间,因此,当用户使用操作系统并在定时器中调用lv_timer_handler时,可能会产生误差,因为它不会实际测量操作系统在空闲线程中花费的时间。

       lv_timer_get_idle函数

       获得lv_timer_handler的空闲时间百分比,其函数原型如下所示:

uint8_t lv_timer_get_idle(void);

        返回值:返回空闲时间百分比。


       6.7.3 定时器API函数

       LVGL官方提供一些与定时器相关的API函数,如下表所示:


表6.7.3.1 定时器相关的API函数描述


       1. lv_timer_del函数

       删除一个定时器,其函数原型如下所示:

void lv_timer_del(lv_timer_t *timer);

        该函数的形参,如下表所示:


表6.7.3.2 lv_timer_del函数形参描述


       返回值:无。

       2. lv_timer_pause函数

       暂停定时器,其函数原型如下所示:

void lv_timer_pause(lv_timer_t *timer);

       该函数的形参,如下表所示:


表6.7.3.3 lv_timer_pause函数形参描述


       返回值:无。

       3. lv_timer_resume函数

       恢复定时器,其函数原型如下所示:

void lv_timer_resume(lv_timer_t *timer);

        该函数的形参,如下表所示:


表6.7.3.4 lv_timer_resume函数形参描述


       返回值:无。

       4. lv_timer_enable函数

       启用或禁用定时器,其函数原型如下所示:

void lv_timer_enable(bool en);

        该函数的形参,如下表所示:


表6.7.3.5 lv_timer_enable函数形参描述


       返回值:无。

       5. lv_timer_get_next函数

       获取下一个定时器,其函数原型如下所示:

lv_timer_t *lv_timer_get_next(lv_timer_t *timer);

        该函数的形参,如下表所示:


表6.7.3.6 lv_timer_get_next函数形参描述


       返回值:返回下一个定时器指针。


        6.8 LVGL 事件


       6.8.1 事件简介

       事件(Event)在LVGL中非常重要,它是连接用户GUI界面和硬件设备(例如LED)之间的桥梁,我们可以将其理解为某种同类型操作动作的集合,例如,短按、长按、按下并释放、聚焦,等等。下面我们以一个LED控制的示例,帮助大家理解事件的作用:


图6.8.1.1 LED控制示例


       在上图的示例中,当用户短按按钮部件(发生事件),将会触发相应的事件回调函数,在该回调函数中,我们可以调用底层的LED驱动,从而实现LED的控制。

       接下来,我们介绍LVGL的事件处理机制,该机制非常完善,它能够监听事件,识别事件源,并完成事件处理,处理机制的示意图如下:


图6.8.1.2 LVGL事件处理机制


       由上图可知,LVGL的事件处理机制分为三部分:

       ① 事件源,能够产生事件的部件,在LVGL中,每一个部件都可以触发事件。

       ② 事件,用户对部件的操作动作,例如:短按、长按等。

       ③ 事件监听器,接收事件、解释事件并处理用户代码。


       6.8.2 添加事件(回调)

       在LVGL中,用户可以调用lv_obj_add_event_cb函数来添加事件,其函数原型如下所示:

struct _lv_event_dsc_t *lv_obj_add_event_cb(lv_obj_t *obj, 
lv_event_cb_t event_cb, 
lv_event_code_t filter,
                                             void *user_data);

       该函数的形参,如下表所示:


表6.8.2.1 lv_obj_add_event_cb函数形参描述


       返回值:返回事件描述符。

       接下来,我们结合源码,为大家介绍事件的添加步骤,示例源码如下:  

/* 第一步 创建按钮部件 */
lv_obj_t *btn = lv_btn_create(lv_scr_act());
/* 第二步 添加事件并设置回调函数 */
lv_obj_add_event_cb(btn, my_event_cb, LV_EVENT_CLICKED, NULL);
 
static void my_event_cb(lv_event_t *event)
{
    printf("Clicked\n");  /* 第三步 在回调函数中处理用户逻辑代码 */
}

       由上述源码可知,部件的事件添加共分为三步:

       ① 创建部件;

       ② 添加事件到部件中,并设置回调函数和事件类型;

       ③ 在回调函数中处理用户逻辑代码。

       注意:事件类型可以理解为某种同类型操作动作的集合,例如短按、长按等,其相关的内容将在6.8.4小节介绍。


       6.8.3 删除事件

       用户可以通过lv_obj_remove_event_cb函数删除事件,其函数原型如下所示:

bool lv_obj_remove_event_cb(struct _lv_obj_t *obj, lv_event_cb_t event_cb);

       该函数的形参,如下表所示:


表6.8.3.1 lv_obj_remove_event_cb函数形参描述


       返回值:true:有事件被移除;false:没有事件被移除。


       6.8.4 事件类型

       事件类型可以理解为某种同类型操作动作的集合,例如短按、长按等,其可分为以下几类:

       ① 输入设备事件;

       ② 绘图事件;

       ③ 其他事件;

       ④ 特别事件;

       ⑤ 自定义事件;

       在LVGL中,所有对象都可以接收输入设备事件、绘图事件和其他事件。注意:自定义事件由用户添加,LVGL 从不发送自定义事件。

       接下来,我们详细介绍这几种事件类型:

       1. 输入设备事件:主要描述触摸、按键等输入设备所触发的事件,如下表所示:


表6.8.4.1 输入设备事件类型


       2. 绘图事件:主要描述部件绘画时的事件,如下表所示:


表6.8.4.2 部件的绘画事件描述


       注意:在部件绘画事件中,不能设置大小等属性,可以获取部件的属性。

       3. 其他事件:主要描述删除、大小、样式等事件,如下表所示:


表6.8.4.3 其他事件描述


       4. 特别事件:主要描述对象数值被修改时触发的事件,如下表所示:


表6.8.4.4 特别事件描述


       注意:关于上述事件类型的使用方法,请回顾6.8.2小节的示例代码。

       5. 自定义事件:

       任何自定义事件代码都可通过以下方式注册:

uint32_t MY_EVENT_1 = lv_event_register_id();

       上述函数可将事件等级表的ID获取回来,然后调用lv_event_send函数,发送事件到回调函数当中。

       lv_event_send函数

       发送一个事件,其函数原型如下所示:

lv_res_t lv_event_send(lv_obj_t *obj, lv_event_code_t event_code, void *param);

       该函数的形参,如下表所示:


表6.8.4.5 lv_event_send函数形参描述


       返回值:LV_RES_OK:发送成功,否则失败。


       6.8.5 获取事件字段

       在LVGL中,允许多个事件共用同一个回调函数,这可以大大减少回调函数的数量,但随之而来的问题是:用户如何去判断事件的信息?例如事件的触发源、事件类型和自定义参数等。为了解决这个问题,LVGL提供了事件字段函数,用于获取事件相关的信息,如下表所示:


表6.8.5.1 获取事件字段函数


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70040860/viewspace-3171769/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2024-08-30

  • 博文量
    588
  • 访问量
    763892