提示:本博客作为学习笔记,有错误的地方希望指正


文章目录

  • 一、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);                              //居中对象
}

esp32c3历程打印checksum failure_参数传递

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);//设置对调函数
}

esp32c3历程打印checksum failure_嵌入式_02

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);  //添加事件回调函数
}

esp32c3历程打印checksum failure_嵌入式_03