提示:本博客作为学习笔记,有错误的地方希望指正
文章目录
- 一、event 简介
- 1.1概述 Overview
- 1.2为对象添加事件 Add events to the object
- 1.3从对象中移除事件 Remove event(s) from an object
- 1.4代码事件 Events code
- 1.5用户事件 Custom events
- 1.6发送事件 Sending events
- 1.7刷新事件 Refresh event
- 1.8事件回调中结构体领域 Fields of lv_event_t
- 1.9冒泡事件 Event bubbling
- 二、事件 API
- 三、示例
- 3.1按键实现事件回调显示
- 3.2按键回调多事件判断检测
- 3.3实现事件添加标志位
一、event 简介
1.1概述 Overview
在LVGL中,当发生一些用户可能感兴趣的事情时,事件就会被触发,例如,一个对象:
点击、滚动、它的值变了、重绘,等等。
1.2为对象添加事件 Add events to the object
用户可以给一个对象分配回调函数来查看它的事件。其中添加的示例如下所示:
lv_obj_t * btn = lv_btn_create(lv_scr_act()); //创建btn对象
lv_obj_add_event_cb(btn, my_event_cb, LV_EVENT_CLICKED, NULL); //添加事件回调
/*callback*/
static void my_event_cb(lv_event_t * event) //事件回调函数
{
printf("Clicked\n");
}
在示例中,LV_EVENT_CLICKED意味着只有单击事件将调用my_event_cb。LV_EVENT_ALL可用于接收所有事件。
lv_obj_add_event_cb的最后一个参数是指向事件中可用的任何自定义数据的指针。
此外我们还可以将更多的事件添加到一个对象中,例如:
lv_obj_add_event_cb(obj, my_event_cb_1, LV_EVENT_CLICKED, NULL);
lv_obj_add_event_cb(obj, my_event_cb_2, LV_EVENT_PRESSED, NULL);
lv_obj_add_event_cb(obj, my_event_cb_3, LV_EVENT_ALL, NULL);
即使相同的事件回调也可以用于具有不同user_data的对象,例如:
lv_obj_add_event_cb(obj, increment_on_click, LV_EVENT_CLICKED, &num1);
lv_obj_add_event_cb(obj, increment_on_click, LV_EVENT_CLICKED, &num2);
事件将按添加时的顺序调用,更多的对象可以使用相同的事件回调。
1.3从对象中移除事件 Remove event(s) from an object
可以使用lv_obj_remove_event_cb(obj, event_cb)函数或lv_obj_remove_event_dsc(obj, event_dsc)从对象中删除事件。Event_dsc是由lv_obj_add_event_cb返回的指针。
1.4代码事件 Events code
代码事件前面btn那篇文章超纲的讲了一部分,这里在叙述一下加深印象。事件的分类:输入设备事件、绘制事件、其他事件、特殊事件、自定义事件。所有对象(如按钮/标签/滑块等),无论其类型如何,都接收输入设备,绘图和其他事件。但是,特殊事件是特定于特定小部件类型的。查看小部件的文档以了解它们何时被发送,自定义事件是由用户添加的,因此这些不会被LVGL发送。
事件代码可以分为以下几类:
• 输入设备的事件
• 绘画事件
• 其他事件
• 特殊事件
• 自定义事件
LV_EVENT_ALL = 0, /**<对象所有事件*/
/**输入设备事件*/
LV_EVENT_PRESSED, /**<对象已被按下*/
LV_EVENT_PRESSING, /**<对象正在被按下(按下时连续调用)*/
LV_EVENT_PRESS_LOST, /**<对象仍在被按下,但将光标/手指滑离对象*/
LV_EVENT_SHORT_CLICKED, /**<对象被短时间的按下,然后释放。不调用,如果滚动*/
LV_EVENT_LONG_PRESSED, /**<对象至少被按下' long_press_time '。不调用,如果滚动*/
LV_EVENT_LONG_PRESSED_REPEAT, /**<在每个`long_press_repeat_time`中`long_press_time`之后调用ms.如果滚动则不调用。*/
LV_EVENT_CLICKED, /**<释放时调用如果没有滚动(无论长按)*/
LV_EVENT_RELEASED, /**<在每次对象被释放时调用*/
LV_EVENT_SCROLL_BEGIN, /**<滚动开始*/
LV_EVENT_SCROLL_END, /**<滚动结束*/
LV_EVENT_SCROLL , /**< 滚动*/
LV_EVENT_GESTURE, /**<检测到手势。使用“lv_indev_get_gesture_dir(lv_indev_get_act())”获得手势*/
LV_EVENT_KEY, /**<一个key被发送到对象。用' lv_indev_get_key(lv_indev_get_act())); '获得键*/
LV_EVENT_FOCUSED, /**<对象被聚焦*/
lv_event_DEFOCUSED, /**<对象离焦*/
LV_EVENT_LEAVE, /**<对象被散焦但仍然被选中*/
LV_EVENT_HIT_TEST, /**<执行高级命中测试*/
* / / * *绘制事件*/
LV_EVENT_COVER_CHECK, /**<检查对象是否完全覆盖了一个区域。事件参数是' lv_cover_check_info_t '*/
lv_event_REFR_ext_draw_size, /**<获得对象周围所需的额外绘制区域(例如阴影)。event参数是' lv_coord_t * '来存储大小*/
LV_EVENT_DRAW_MAIN_BEGIN, /**<开始主绘图阶段*/
LV_EVENT_DRAW_MAIN, /**<执行主绘图*/
LV_EVENT_DRAW_MAIN_END, /**<完成主绘图阶段*/
LV_EVENT_DRAW_POST_BEGIN, /**<开始post绘制阶段(当所有子元素绘制完成时)*/
LV_EVENT_DRAW_POST, /**<执行post绘制阶段(当所有子元素都绘制时)*/
LV_EVENT_DRAW_POST_END, /**<完成post绘制阶段(当所有子元素都绘制时)*/
LV_EVENT_DRAW_PART_BEGIN, /**<开始绘制零件。事件参数是' lv_obj_draw_dsc_t * '。*/
LV_EVENT_DRAW_PART_END, /**<绘制零件结束。事件参数是' lv_obj_draw_dsc_t * '。*/
* / / * *特别事件*/
LV_EVENT_VALUE_CHANGED, /**<对象的值已经改变(即滑块移动)*/
LV_EVENT_INSERT, /**<将文本插入到对象中。事件数据是' char * '正在插入*/
LV_EVENT_REFRESH, /**<通知对象刷新其上的某些内容(为用户)*/
LV_EVENT_READY, /**<进程已完成*/
LV_EVENT_CANCEL, /**<进程已被取消*/
* / / * *其他事件*/
LV_EVENT_DELETE, /**<对象正在被删除*/
LV_EVENT_CHILD_CHANGED, /**< Child was removed/added*/
LV_EVENT_SIZE_CHANGED, /**<对象坐标/大小已更改*/
LV_EVENT_STYLE_CHANGED, /**<对象的样式已更改*/
LV_EVENT_LAYOUT_CHANGED, /**<子节点的位置由于布局重新计算而改变*/
LV_EVENT_GET_SELF_SIZE, /**<获取小部件的内部大小*/
_LV_EVENT_LAST /**默认事件个数*/
1.5用户事件 Custom events
MY_EVENT_1 = lv_event_register_id()可以注册任何自定义事件代码;并且可以通过lv_event_send(obj, MY_EVENT_1, &some_data)发送到任何对象。
1.6发送事件 Sending events
手动发送事件到一个对象,使用lv_event_send(obj, <EVENT_CODE> &some_data)。
例如,它可以用来手动关闭一个消息框,通过模拟一个按钮按下(尽管有更简单的方法):
uint32_t btn_id = 0;
lv_event_send(mbox, LV_EVENT_VALUE_CHANGED, &btn_id);
1.7刷新事件 Refresh event
LV_EVENT_REFRESH是一个特殊事件,因为它被设计为用户用来通知对象刷新自己。一些例子:
1、根据一个或多个变量(例如当前时间)通知标签刷新其文本
2、当语言改变时刷新标签
3、如果符合某些条件(例如输入正确的密码),启用一个按钮
4、如果超出了限制,可以向对象添加或从对象中删除样式,等等
1.8事件回调中结构体领域 Fields of lv_event_t
lv_event_t 是传递给事件回调的唯一参数,它包含关于事件的所有数据。
typedef struct _lv_event_t {
struct _lv_obj_t * target; //获得事件最初瞄准的对象。即使事件是冒泡的,也是一样的。
struct _lv_obj_t * current_target; //获取事件的当前目标。它是被调用事件处理程序的对象。
lv_event_code_t code; //获取事件的事件代码
void * user_data; //获取在对象上注册事件时传递的user_data
void * param; //当事件被发送时,获取参数传递
struct _lv_event_t * prev;
uint8_t deleted : 1;
} lv_event_t;
Lv_event_t是传递给事件回调的唯一参数,它包含关于事件的所有数据。以下值可以从它中获得:
lv_event_get_code(e) //获取事件代码
lv_event_get_current_target(e) //获取发送事件的对象。即对象事件处理程序正在被调用。
lv_event_get_target(e) //获取最初触发事件的对象(与Lv_event_get_target(如果启用了事件冒泡)
lv_event_get_user_data(e) //获取作为lv_obj_add_event_cb的最后一个参数传递的指针。
lv_event_get_param(e) //获取传递的参数作为lv_event_send的最后一个参数
1.9冒泡事件 Event bubbling
如果 lv_obj_add_flag(obj, LV_OBJ_FLAG_EVENT_BUBBLE) 所有的事件也会被发送到对象的父对象。如果父进程也启用了LV_OBJ_FLAG_EVENT_BUBBLE,那么该事件也将被发送到它的父进程,以此类推。事件的目标参数总是当前目标对象,而不是原始对象。要获取原始目标,请在事件处理程序中调用lv_event_get_original_target(e)。
二、事件 API
事件的API
lv_res_t lv_event_send(lv_obj_t * obj, lv_event_code_t event_code, void * param) //发送一个事件给对象
lv_res_t lv_obj_event_base(const lv_obj_class_t * class_p, lv_event_t * e) //由小部件内部使用,调用祖先小部件类型的事件处理程序
lv_obj_t * lv_event_get_target(lv_event_t * e) //获得事件最初瞄准的对象。即使事件是冒泡的,也是一样的。
lv_obj_t * lv_event_get_current_target(lv_event_t * e) //获取事件的当前目标。它是被调用事件处理程序的对象。
lv_event_code_t lv_event_get_code(lv_event_t * e) //获取事件的事件代码
void * lv_event_get_param(lv_event_t * e) //当事件被发送时,获取参数传递
void * lv_event_get_user_data(lv_event_t * e) //获取在对象上注册事件时传递的user_data
uint32_t lv_event_register_id(void) //注册一个新的自定义事件ID。
void _lv_event_mark_deleted(lv_obj_t * obj) //可以调用嵌套事件,其中一个可能属于正在删除的对象。
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) //为对象添加一个事件处理函数。
bool lv_obj_remove_event_dsc(lv_obj_t * obj, struct _lv_event_dsc_t * event_dsc) //移除一个对象的事件处理函数。
lv_indev_t * lv_event_get_indev(lv_event_t * e) //获取作为参数传递给indev相关事件的输入设备。
lv_obj_draw_part_dsc_t * lv_event_get_draw_part_dsc(lv_event_t * e) //获得零件绘制描述符作为参数传递到' LV_EVENT_DRAW_PART_BEGIN/END '。
const lv_area_t * lv_event_get_clip_area(lv_event_t * e) //获取剪辑区域作为参数来绘制事件事件。
const lv_area_t * lv_event_get_old_size(lv_event_t * e) //获取对象改变大小之前的旧区域。可以在' LV_EVENT_SIZE_CHANGED '中使用
uint32_t lv_event_get_key(lv_event_t * e) //获取作为参数传递给事件的密钥。可以在' LV_EVENT_KEY '中使用
lv_anim_t * lv_event_get_scroll_anim(lv_event_t * e) //获取滚动的动画描述符。可以在' LV_EVENT_SCROLL_BEGIN '中使用
void lv_event_set_ext_draw_size(lv_event_t * e, lv_coord_t size) //设置新的额外绘制尺寸。可以在' lv_event_ref_ext_draw_size '中使用
lv_point_t * lv_event_get_self_size_info(lv_event_t * e) //获取一个指向' lv_point_t '变量的指针,其中自我大小应该保存(宽度在' point->x '和高度' point->y ')。
lv_hit_test_info_t * lv_event_get_hit_test_info(lv_event_t * e) //获取一个指向' lv_hit_test_info_t '变量的指针,该变量将保存命中测试结果。可以在' LV_EVENT_HIT_TEST '中使用
const lv_area_t * lv_event_get_cover_area(lv_event_t * e) //获取一个指向区域的指针,该区域应该被检查对象是否完全覆盖它。
void lv_event_set_cover_res(lv_event_t * e, lv_cover_res_t res) //设置封面检查的结果。可以在' LV_EVENT_COVER_CHECK '中使用
三、示例
3.1按键实现事件回调显示
/*************************************************
* 函数名称 : btn_event_cb
* 参 数 : 无
* 函数功能 : 按键事件回调显示
*************************************************/
static void btn_event_cb(lv_event_t * e)
{
static unsigned int cnt = 1;
lv_obj_t *btn = lv_event_get_target(e); //获得事件最初瞄准的对象。即使事件是冒泡的,也是一样的。
lv_obj_t * label = lv_obj_get_child(btn,0); //通过子对象的索引获取子对象。
lv_label_set_text_fmt(label,"%u",cnt); //为标签设置一个新的格式化文本。内存将分配给存储文本的标签。
cnt++;
}
/*************************************************
* 函数名称 : event_show_1
* 参 数 : 无
* 函数功能 : 实现事件回调函数
*************************************************/
void event_show_1()
{
lv_obj_t * btn = lv_btn_create(lv_scr_act()); //创建btn对象
lv_obj_set_size(btn,100,50); //设置对象尺寸
lv_obj_center(btn); //居中对象
lv_obj_add_event_cb(btn,btn_event_cb,LV_EVENT_CLICKED,NULL); //添加对象回调函数
lv_obj_t * label = lv_label_create(btn); //创建label
lv_label_set_text(label,"Click me!"); //设置label的文字
lv_obj_center(label); //居中对象
}
3.2按键回调多事件判断检测
/*************************************************
* 函数名称 : event_show_cb
* 参 数 : 无
* 函数功能 : 按键事件回调显示
*************************************************/
static void event_show2_cb(lv_event_t * e)
{
lv_event_code_t code = lv_event_get_code(e); //获取事件的事件代码
lv_obj_t * label = lv_event_get_user_data(e); //获取用户携带数据
switch(code){
case LV_EVENT_PRESSED: //按压事件
lv_label_set_text(label,"The last button event:\nLV_EVENT_PRESSED");
break;
case LV_EVENT_CLICKED: //点击事件
lv_label_set_text(label,"The last button event:\nLV_EVENT_CLICKED");
break;
case LV_EVENT_LONG_PRESSED: //长按压事件
lv_label_set_text(label,"The last button event:\nLV_EVENT_LONG_PRESSED");
break;
case LV_EVENT_LONG_PRESSED_REPEAT: //重复按压事件
lv_label_set_text(label,"The last button event:\nLV_EVENT_LONG_PRESSED_REPEAT");
break;
case LV_EVENT_KEY: //KEY事件
lv_label_set_text(label,"The last button event:\nLV_EVENT_KEY");
break;
default:
break;
}
}
/*************************************************
* 函数名称 : event_show_2
* 参 数 : 无
* 函数功能 : 按键联动,实现Label动画显示
*************************************************/
void event_show_2()
{
lv_obj_t * btn = lv_btn_create(lv_scr_act()); //创建按钮对象
lv_obj_set_size(btn,100,50); //设置按钮尺寸
lv_obj_center(btn); //居中对象
lv_obj_t * btn_label = lv_label_create(btn); //创建label
lv_label_set_text(btn_label,"Click Me!"); //设置字内容
lv_obj_center(btn_label); //居中
lv_obj_t * info_label = lv_label_create(lv_scr_act()); //创建label
lv_label_set_text(info_label,"The last button event:\nNone"); //设置label内容
lv_obj_add_event_cb(btn,event_show2_cb,LV_EVENT_ALL,info_label);//设置对调函数
}
3.3实现事件添加标志位
/*************************************************
* 函数名称 : event_show_3_cb
* 参 数 : 无
* 函数功能 : 事件回调函数
*************************************************/
static void event_show_3_cb (lv_event_t * e)
{
lv_obj_t * target = lv_event_get_target(e); //获得事件最初瞄准的对象。即使事件是冒泡的,也是一样的。
lv_obj_t * cont = lv_event_get_current_target(e); //获取事件的当前目标。它是被调用事件处理程序的对象。
if(target == cont) return; //判断最初瞄准对象和当前获取的对象是否一致
lv_obj_set_style_bg_color(target,lv_palette_main(LV_PALETTE_RED),0); //设置对象背景颜色
}
/*************************************************
* 函数名称 : event_show_3
* 参 数 : 无
* 函数功能 : 事件联动
*************************************************/
void event_show_3()
{
lv_obj_t * cont = lv_obj_create(lv_scr_act()); //创建对象
lv_obj_set_size(cont,290,200); //设置对象尺寸
lv_obj_center(cont); //居中对象
lv_obj_set_flex_flow(cont,LV_FLEX_FLOW_ROW_WRAP); //设置对象伸缩流 LV_FLEX_FLOW_ROW_WRAP 伸缩流行缠绕
unsigned int i;
for(i=0;i<30;i++){
lv_obj_t * btn = lv_btn_create(cont); //创建对象
lv_obj_set_size(btn,80,50); //设置对象尺寸
lv_obj_add_flag(btn,LV_OBJ_FLAG_EVENT_BUBBLE); //添加对象标志位 对象标志事件气泡
lv_obj_t * label = lv_label_create(btn); //创建Label
lv_label_set_text_fmt(label,"%u",i); //设置Label显示内容
lv_obj_center(label); //居中对象
}
lv_obj_add_event_cb(cont,event_show_3_cb,LV_EVENT_CLICKED,NULL); //添加事件回调函数
}