【LVGL(4)】对象的事件及事件冒泡 您所在的位置:网站首页 事件处理 【LVGL(4)】对象的事件及事件冒泡

【LVGL(4)】对象的事件及事件冒泡

2023-06-15 13:29| 来源: 网络整理| 查看: 265

LVGL官方文档:Welcome to the documentation of LVGL! — LVGL documentationhttps://docs.lvgl.io/master/index.html

事件(events)

点击、滚动、数组改变、重绘……

事件类型 输入设备事件(Input device events) 绘图事件(Drawing events) 其他事件(Special events) 特殊事件(Other events) 自定义事件(Custom events)

看文档啦 ~ Events — LVGL documentation

添加事件 lv_obj_add_event_cb(obj, event_cb, event_code, user_data);

参数:对象,处理(cb:callbackfunction,回调函数),事件类型,用户数据

发送事件 lv_event_send(obj, event_cb, event_code, user_data); 删除事件 lv_obj_remove_event_cb(obj, event_cb); lv_obj_remove_event_dsc(obj, event_dsc); //event_dsc 是 lv_obj_add_event_cb 返回的指针

最简单的事件:

static void function() { printf("test\n"); } void mode(void) { lv_obj_t * obj = lv_obj_create(lv_scr_act()); lv_obj_add_event_cb(obj,function,LV_EVENT_CLICKED,NULL); //按键点击,释放后调用 }

被调用的函数是可以传入参数的

function(lv_event_t * e) typedef struct _lv_event_t { struct _lv_obj_t * target; //触发事件的对象 struct _lv_obj_t * current_target; //父级触发事件的对象 lv_event_code_t code; //事件代码 void * user_data; //用户数据 void * param; struct _lv_event_t * prev; uint8_t deleted : 1; uint8_t stop_processing : 1; uint8_t stop_bubbling : 1; } lv_event_t;

如下,写了个点灯的接口

int count = 0; static void function1(lv_event_t * e) { lv_obj_t * obj = lv_event_get_target(e); // 获取触发事件的部件(对象) lv_event_code_t code = lv_event_get_code(e); // 获取当前部件(对象)触发的事件代码 lv_obj_t * label = lv_event_get_user_data(e); // 获取添加事件时传递的用户数据 if(count == 0 && code == LV_EVENT_PRESSED) { lv_label_set_text(label, "OPEN"); lv_obj_set_style_bg_color(obj, lv_color_hex(0xc43e1c), 0); // 通过本地样式(私有样式)设置背景色 printf("OPEN\n"); count ++; } else if(count == 1 && code == LV_EVENT_PRESSED) { lv_label_set_text(label, "CLOSE"); lv_obj_set_style_bg_color(obj, lv_color_hex(0xffffff), 0); // 通过本地样式(私有样式)设置背景色 printf("CLOSE\n"); count ++; } if(count==2) count = 0; } void lv_100ask_demo_course_2_2_6(void) { /* 创建基础部件(对象) */ lv_obj_t * obj = lv_obj_create(lv_scr_act()); lv_obj_center(obj); //放在中心 /* 创建label部件(对象) */ lv_obj_t * label = lv_label_create(lv_scr_act()); lv_label_set_text(label, "CLOSE"); // 设置label展示的文字 lv_obj_center(label); // 将对象与其父对象的中心对齐,这里的父对象是屏幕:lv_scr_act() // 为obj1添加事件回调函数,所有的事件类型都能触发该回调函数 lv_obj_add_event_cb(obj, function1, LV_EVENT_ALL, label);//传入的是label,可设置label }

现象:

点击开灯:

 点击关灯:

事件冒泡

如果对象启用了 lv_obj_add_flag(obj, LV_OBJ_FLAG_EVENT_BUBBLE),该对象的所有事件将会发送到该对象的父级。如果父级也启用了 LV_OBJ_FLAG_EVENT_BUBBLE,那么事件继续发送到他的父级,依此类推。

lv_event_get_target(e); 获取触发事件的当前对象。  lv_event_get_current_target(e); 获取事件冒泡的父对象。 static void my_event_cb(lv_event_t * e) { lv_obj_t * obj = lv_event_get_target(e); // 获取触发事件的对象 lv_obj_t * parent = lv_event_get_current_target(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, "LV_EVENT_PRESSED"); /* 父级 */ lv_obj_set_style_bg_color(parent, lv_color_hex(0xc43e1c), 0); // 通过本地样式(私有样式)设置背景色 /* 触发事件本身对象 */ lv_obj_set_style_bg_color(obj, lv_color_hex(0xc43e1c), 0); // 通过本地样式(私有样式)设置背景色 printf("LV_EVENT_PRESSED\n"); break; case LV_EVENT_CLICKED: //松开的时候产生了点击 lv_label_set_text(label, "LV_EVENT_CLICKED"); lv_obj_remove_local_style_prop(parent, LV_STYLE_BG_COLOR, 0); // 删除通过本地样式(私有样式)设置的背景色 lv_obj_remove_local_style_prop(obj, LV_STYLE_BG_COLOR, 0); // 删除通过本地样式(私有样式)设置的背景色 printf("LV_EVENT_CLICKED\n"); break; default: //printf("NONE\n"); break; } } void lv_100ask_demo_course_2_2_6(void) { /* 创建一个基础对象 obj1 */ lv_obj_t * obj1 = lv_obj_create(lv_scr_act()); lv_obj_set_size(obj1, 450, 250); lv_obj_center(obj1); // 将对象与其父对象的中心对齐,这里的父对象是屏幕:lv_scr_act() /* 以 obj1 创建一个基础对象 obj2 */ lv_obj_t * obj2 = lv_obj_create(obj1); lv_obj_set_size(obj2, 400, 200); lv_obj_center(obj2); // 将对象与其父对象的中心对齐,这里的父对象是屏幕:obj1 lv_obj_add_flag(obj2, LV_OBJ_FLAG_EVENT_BUBBLE); // 启用事件冒泡,将接收到的所有事件传播给父级 /* 以 obj2 创建一个基础对象 obj3 */ lv_obj_t * obj3 = lv_obj_create(obj2); lv_obj_set_size(obj3, 350, 150); lv_obj_center(obj3); // 将对象与其父对象的中心对齐,这里的父对象是屏幕:obj2 lv_obj_add_flag(obj3, LV_OBJ_FLAG_EVENT_BUBBLE); // 启用事件冒泡,将接收到的所有事件传播给父级 /* 以 obj3 创建一个基础对象 obj4 */ lv_obj_t * obj4 = lv_obj_create(obj3); lv_obj_set_size(obj4, 300, 100); lv_obj_center(obj4); // 将对象与其父对象的中心对齐,这里的父对象是屏幕:obj3 lv_obj_add_flag(obj4, LV_OBJ_FLAG_EVENT_BUBBLE); // 启用事件冒泡,将接收到的所有事件传播给父级 /* 以屏幕为父类,创建一个label部件(对象) */ lv_obj_t * label = lv_label_create(lv_scr_act()); lv_label_set_text(label, "test"); // 设置label展示的文字 lv_obj_align_to(label, obj1, LV_ALIGN_OUT_TOP_MID, 0, 0); // 将label相对于obj1对齐 // 将给obj1添加事件回调函数,所有的事件类型都能触发该回调函数 lv_obj_add_event_cb(obj1, my_event_cb, LV_EVENT_ALL, label); }

哈哈哈哈 ~ 真的很有意思呢 ~

现象:

点击最中间对象:

点击第三层对象:

 点击第二层对象:

 最外层对象:

事件说明

一个事件回调函数可给多个对象使用

我们创建了一个事件处理函数之后是可以给不同的对象使用的。

一个对象可以使用多个事件回调函数

我们创建的对象可以绑定多个事件,比如一个事件是处理点击类型的事件,一个事件处理按下类型的事件等等。

其他

如果传入的用户数据不一样,一个对象可以绑定同一个事件回调函数多次,事件将按照添加的顺序调用。例如:

lv_obj_add_event_cb(obj, my_clicked_event_cb, LV_EVENT_CLICKED, &num1);lv_obj_add_event_cb(obj, my_clicked_event_cb, LV_EVENT_CLICKED, &num2);

OK,这样就能实现简单的函数调用功能了,至少目前一直到开发板上可以当个点灯开关使用了。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有