Events(事件)¶
查看原文
Events are triggered in LVGL when something happens which might be interesting to the user, e.g. when an object
is clicked
is scrolled
has its value changed
is redrawn, etc.
当发生用户可能感兴趣的事情时,LVGL 中会触发事件,例如当一个对象
被点击
滚动
数值被改变
重绘等。
Add events to the object¶
查看原文
The user can assign callback functions to an object to see its events. In practice, it looks like this:
用户可以为对象分配回调函数以查看其事件。在实践中,它看起来像这样:
lv_obj_t * btn = lv_btn_create(lv_scr_act());
lv_obj_add_event_cb(btn, my_event_cb, LV_EVENT_CLICKED, NULL); /*Assign an event callback*/
...
static void my_event_cb(lv_event_t * event)
{
printf("Clicked\n");
}
查看原文
In the example LV_EVENT_CLICKED
means that only the click event will call my_event_cb
. See the list of event codes for all the options.
LV_EVENT_ALL
can be used to receive all the events.
The last parameter of lv_obj_add_event_cb
is a pointer to any custom data that will be available in the event. It will be described later in more detail.
More events can be added to an object, like this:
在示例中 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); /*No filtering, receive all events*/
查看原文
Even the same event callback can be used on an object with different user_data
. For example:
如果传入的用户数据不一样,一个对象可以绑定同一个事件回调函数多次。例如:
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);
查看原文
The events will be called in the order as they were added.
More objects can use the same event callback.
这些事件将按照添加的顺序被调用。
更多的对象可以使用相同的 事件回调。
Remove event(s) from an object(从对象中删除事件)¶
查看原文
Events can be removed from an object with the lv_obj_remove_event_cb(obj, event_cb)
function or lv_obj_remove_event_dsc(obj, event_dsc)
. event_dsc
is a pointer returned by lv_obj_add_event_cb
.
可以使用 lv_obj_remove_event_cb(obj, event_cb)
函数或 lv_obj_remove_event_dsc(obj, event_dsc)
从对象中删除事件。 event_dsc
是一个由 lv_obj_add_event_cb
返回的指针。
Event codes¶
查看原文
The event codes can be grouped into these categories:
Input device events
Drawing events
Other events
Special events
Custom events
All objects (such as Buttons/Labels/Sliders etc.) regardless their type receive the Input device, Drawing and Other events.
However the Special events are specific to a particular widget type. See the widgets' documentation to learn when they are sent,
Custom events are added by the user and therefore these are never sent by LVGL.
The following event codes exist:
事件代码可以分为以下几类:
输入设备事件(Input device events)
绘图事件(Drawing events)
其他事件(Special events)
特殊事件(Other events)
自定义事件(Custom events)
请查阅源码:lvgl/src/core/lv_event.h (lv_event_code_t)
所有对象(例如按钮/标签/滑块等),无论其类型如何,都会接收 Input device、Drawing 和 Other 事件。
然而,特殊事件 特定于特定的小部件类型。查看 widgets' 文档 了解何时发送,
自定义事件 由用户添加,因此这些事件永远不会由 LVGL 发送。
存在以下事件代码:
Input device events(输入设备事件)¶
查看原文
LV_EVENT_PRESSED
The object has been pressedLV_EVENT_PRESSING
The object is being pressed (called continuously while pressing)LV_EVENT_PRESS_LOST
The object is still being pressed but slid cursor/finger off of the objectLV_EVENT_SHORT_CLICKED
The object was pressed for a short period of time, then released it. Not called if scrolled.LV_EVENT_LONG_PRESSED
Object has been pressed for at least thelong_press_time
specified in the input device driver. Not called if scrolled.LV_EVENT_LONG_PRESSED_REPEAT
Called afterlong_press_time
in everylong_press_repeat_time
ms. Not called if scrolled.LV_EVENT_CLICKED
Called on release if the object did not scroll (regardless of long press)LV_EVENT_RELEASED
Called in every case when the object has been releasedLV_EVENT_SCROLL_BEGIN
Scrolling begins. The event paramter isNULL
or anlv_anim_t *
with the scroll animation descriptor to modify if required.LV_EVENT_SCROLL_END
Scrolling ends.LV_EVENT_SCROLL
The object was scrolledLV_EVENT_GESTURE
A gesture is detected. Get the gesture withlv_indev_get_gesture_dir(lv_indev_get_act());
LV_EVENT_KEY
A key is sent to the object. Get the key withlv_indev_get_key(lv_indev_get_act());
LV_EVENT_FOCUSED
The object is focusedLV_EVENT_DEFOCUSED
The object is defocusedLV_EVENT_LEAVE
The object is defocused but still selectedLV_EVENT_HIT_TEST
Perform advanced hit-testing. Uselv_hit_test_info_t * a = lv_event_get_hit_test_info(e)
and check ifa->point
can click the object or not. If not seta->res = false
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
之后调用。如果滚动则不会调用。LV_EVENT_CLICKED
如果对象没有滚动,则在释放时调用(无论是否长按)LV_EVENT_RELEASED
在对象被释放后的每种情况下调用LV_EVENT_SCROLL_BEGIN
开始滚动。事件参数是NULL
或lv_anim_t *
,如果需要,可以修改滚动动画描述符。LV_EVENT_SCROLL_END
滚动结束。LV_EVENT_SCROLL
对象被滚动LV_EVENT_GESTURE
检测到手势。使用lv_indev_get_gesture_dir(lv_indev_get_act());
获取手势LV_EVENT_KEY
一个密钥被发送到对象。使用lv_indev_get_key(lv_indev_get_act());
获取密钥LV_EVENT_FOCUSED
对象被聚焦LV_EVENT_DEFOCUSED
对象散焦LV_EVENT_LEAVE
对象散焦但仍被选中LV_EVENT_HIT_TEST
执行高级命中测试。使用lv_hit_test_info_t * a = lv_event_get_hit_test_info(e)
并检查a->point
是否可以点击对象。如果没有则a->res = false
Drawing events(绘图事件)¶
查看原文
LV_EVENT_COVER_CHECK
Check if the object fully covers an area. The event parameter islv_cover_check_info_t *
.LV_EVENT_REFR_EXT_DRAW_SIZE
Get the required extra draw area around the object (e.g. for shadow). The event parameter islv_coord_t *
to store the size. Overwrite it only with a larger value.LV_EVENT_DRAW_MAIN_BEGIN
Starting the main drawing phase.LV_EVENT_DRAW_MAIN
Perform the main drawingLV_EVENT_DRAW_MAIN_END
Finishing the main drawing phaseLV_EVENT_DRAW_POST_BEGIN
Starting the post draw phase (when all children are drawn)LV_EVENT_DRAW_POST
Perform the post draw phase (when all children are drawn)LV_EVENT_DRAW_POST_END
Finishing the post draw phase (when all children are drawn)LV_EVENT_DRAW_PART_BEGIN
Starting to draw a part. The event parameter islv_obj_draw_dsc_t *
. Learn more here.LV_EVENT_DRAW_PART_END
Finishing to draw a part. The event parameter islv_obj_draw_dsc_t *
. Learn more here.
LV_EVENT_COVER_CHECK
检查对象是否完全覆盖一个区域。事件参数是lv_cover_check_info_t *
。LV_EVENT_REFR_EXT_DRAW_SIZE
获取对象周围所需的额外绘制区域(例如用于阴影)。事件参数是lv_coord_t *
来存储大小。仅用更大的值覆盖它。LV_EVENT_DRAW_MAIN_BEGIN
开始主绘图阶段。LV_EVENT_DRAW_MAIN
执行主绘图LV_EVENT_DRAW_MAIN_END
完成主绘制阶段LV_EVENT_DRAW_POST_BEGIN
开始后期绘制阶段(当所有孩子都被绘制时)LV_EVENT_DRAW_POST
执行后期绘制阶段(当所有孩子都被绘制时)LV_EVENT_DRAW_POST_END
完成后期绘制阶段(当所有孩子都被绘制时)LV_EVENT_DRAW_PART_BEGIN
开始绘制零件。事件参数是lv_obj_draw_dsc_t *
。了解更多 此处。LV_EVENT_DRAW_PART_END
完成绘制零件。事件参数是lv_obj_draw_dsc_t *
。了解更多 此处。
Other events(其他事件)¶
查看原文
LV_EVENT_DELETE
Object is being deletedLV_EVENT_CHILD_CHANGED
Child was removed/addedLV_EVENT_SIZE_CHANGED
Object coordinates/size have changedLV_EVENT_STYLE_CHANGED
Object's style has changedLV_EVENT_BASE_DIR_CHANGED
The base dir has changedLV_EVENT_GET_SELF_SIZE
Get the internal size of a widget
LV_EVENT_DELETE
对象正在被删除LV_EVENT_CHILD_CHANGED
孩子被移除/添加LV_EVENT_SIZE_CHANGED
对象坐标/大小已更改LV_EVENT_STYLE_CHANGED
对象的样式已更改LV_EVENT_BASE_DIR_CHANGED
基础目录已经改变LV_EVENT_GET_SELF_SIZE
获取小部件的内部尺寸
Special events(特殊事件)¶
查看原文
LV_EVENT_VALUE_CHANGED
The object's value has changed (i.e. slider moved)LV_EVENT_INSERT
A text is being inserted to the object. The event data ischar *
being inserted.LV_EVENT_REFRESH
Notify the object to refresh something on it (for the user)LV_EVENT_READY
A process has finishedLV_EVENT_CANCEL
A process has been canceled
LV_EVENT_VALUE_CHANGED
对象的值已更改(即滑块移动)LV_EVENT_INSERT
正在向对象插入文本。事件数据是插入的char *
。LV_EVENT_REFRESH
通知对象刷新其上的某些内容(对于用户)LV_EVENT_READY
一个过程已经完成LV_EVENT_CANCEL
一个过程被取消
Custom events(自定义事件)¶
查看原文
Any custom event codes can be registered by uint32_t MY_EVENT_1 = lv_event_register_id();
And can be sent to any object with lv_event_send(obj, MY_EVENT_1, &some_data)
任何自定义事件代码都可以通过 uint32_t MY_EVENT_1 = lv_event_register_id();
注册
并且可以使用 lv_event_send(obj, MY_EVENT_1, &some_data)
发送到任何对象
Sending events(发送事件)¶
查看原文
To manually send events to an object, use lv_event_send(obj, <EVENT_CODE> &some_data)
.
For example, this can be used to manually close a message box by simulating a button press (although there are simpler ways to do this):
要手动向对象发送事件,请使用 lv_event_send(obj, <EVENT_CODE> &some_data)
。
例如,这可用于通过模拟按钮按下来手动关闭消息框(尽管有更简单的方法可以做到这一点):
/*Simulate the press of the first button (indexes start from zero)*/
uint32_t btn_id = 0;
lv_event_send(mbox, LV_EVENT_VALUE_CHANGED, &btn_id);
Refresh event(刷新事件)¶
查看原文
LV_EVENT_REFRESH
is special event because it's designed to be used by the user to notify an object to refresh itself. Some examples:
notify a label to refresh its text according to one or more variables (e.g. current time)
refresh a label when the language changes
enable a button if some conditions are met (e.g. the correct PIN is entered)
add/remove styles to/from an object if a limit is exceeded, etc
LV_EVENT_REFRESH
是一个特殊事件,因为它被设计为用户使用它来通知对象刷新自身。一些例子:
通知标签根据一个或多个变量(例如当前时间)刷新其文本
当语言改变时刷新标签
如果满足某些条件(例如输入正确的 PIN),则启用按钮
如果超出限制,则向/从对象添加/删除样式等
Fields of lv_event_t(lv_event_t 的字段)¶
查看原文
lv_event_t
is the only parameter passed to event callback and it contains all the data about the event. The following values can be gotten from it:
lv_event_get_code(e)
get the event codelv_event_get_target(e)
get the object to which the event is sentlv_event_get_original_target(e)
get the object to which the event is sent originally sent (different fromlv_event_get_target
if event bubbling is enabled)lv_event_get_user_data(e)
get the pointer passed as the last parameter oflv_obj_add_event_cb
.lv_event_get_param(e)
get the parameter passed as the last parameter oflv_event_send
lv_event_t
是传递给事件回调的唯一参数,它包含有关事件的所有数据。可以从中获得以下值:
lv_event_get_code(e)
获取触发的事件代码lv_event_get_target(e)
获取事件发送到(关联)的对象lv_event_get_original_target(e)
获取事件最初发送到的对象(与lv_event_get_target
不同,如果 event bubbling 被启用)lv_event_get_user_data(e)
获取作为lv_obj_add_event_cb
的最后一个参数传递的指针。lv_event_get_param(e)
获取作为lv_event_send
的最后一个参数传递的参数
Event bubbling(事件冒泡)¶
查看原文
If lv_obj_add_flag(obj, LV_OBJ_FLAG_EVENT_BUBBLE)
is enabled all events will be sent to the object's parent too. If the parent also has LV_OBJ_FLAG_EVENT_BUBBLE
enabled the event will be sent to its parent too, and so on.
The target parameter of the event is always the current target object, not the original object. To get the original target call lv_event_get_original_target(e)
in the event handler.
如果启用了 lv_obj_add_flag(obj, LV_OBJ_FLAG_EVENT_BUBBLE)
,所有事件也将发送到对象的父级。如果父级也启用了LV_OBJ_FLAG_EVENT_BUBBLE
,则事件也将发送到其父级,依此类推。
事件的 target 参数始终是当前目标对象,而不是原始对象。在事件处理程序中获取原始目标调用 lv_event_get_original_target(e)
。
Examples¶
Button click event¶
C code
GitHub#include "../lv_examples.h"
#if LV_BUILD_EXAMPLES && LV_USE_SWITCH
static void event_cb(lv_event_t * e)
{
LV_LOG_USER("Clicked");
static uint32_t 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, "%"LV_PRIu32, cnt);
cnt++;
}
/**
* Add click event to a button
*/
void lv_example_event_1(void)
{
lv_obj_t * btn = lv_btn_create(lv_scr_act());
lv_obj_set_size(btn, 100, 50);
lv_obj_center(btn);
lv_obj_add_event_cb(btn, event_cb, LV_EVENT_CLICKED, NULL);
lv_obj_t * label = lv_label_create(btn);
lv_label_set_text(label, "Click me!");
lv_obj_center(label);
}
#endif
class Event_1():
def __init__(self):
self.cnt = 1
#
# Add click event to a button
#
btn = lv.btn(lv.scr_act())
btn.set_size(100, 50)
btn.center()
btn.add_event_cb(self.event_cb, lv.EVENT.CLICKED, None)
label = lv.label(btn)
label.set_text("Click me!")
label.center()
def event_cb(self,e):
print("Clicked")
btn = e.get_target()
label = btn.get_child(0)
label.set_text(str(self.cnt))
self.cnt += 1
evt1 = Event_1()
Handle multiple events¶
C code
GitHub#include "../lv_examples.h"
#if LV_BUILD_EXAMPLES && LV_USE_SWITCH
static void event_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;
default:
break;
}
}
/**
* Handle multiple events
*/
void lv_example_event_2(void)
{
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);
lv_label_set_text(btn_label, "Click me!");
lv_obj_center(btn_label);
lv_obj_t * info_label = lv_label_create(lv_scr_act());
lv_label_set_text(info_label, "The last button event:\nNone");
lv_obj_add_event_cb(btn, event_cb, LV_EVENT_ALL, info_label);
}
#endif
def event_cb(e,label):
code = e.get_code()
if code == lv.EVENT.PRESSED:
label.set_text("The last button event:\nLV_EVENT_PRESSED")
elif code == lv.EVENT.CLICKED:
label.set_text("The last button event:\nLV_EVENT_CLICKED")
elif code == lv.EVENT.LONG_PRESSED:
label.set_text("The last button event:\nLV_EVENT_LONG_PRESSED")
elif code == lv.EVENT.LONG_PRESSED_REPEAT:
label.set_text("The last button event:\nLV_EVENT_LONG_PRESSED_REPEAT")
btn = lv.btn(lv.scr_act())
btn.set_size(100, 50)
btn.center()
btn_label = lv.label(btn)
btn_label.set_text("Click me!")
btn_label.center()
info_label = lv.label(lv.scr_act())
info_label.set_text("The last button event:\nNone")
btn.add_event_cb(lambda e: event_cb(e,info_label), lv.EVENT.ALL, None)
Event bubbling¶
C code
GitHub#include "../lv_examples.h"
#if LV_BUILD_EXAMPLES && LV_USE_FLEX
static void event_cb(lv_event_t * e)
{
/*The original target of the event. Can be the buttons or the container*/
lv_obj_t * target = lv_event_get_target(e);
/*The current target is always the container as the event is added to it*/
lv_obj_t * cont = lv_event_get_current_target(e);
/*If container was clicked do nothing*/
if(target == cont) return;
/*Make the clicked buttons red*/
lv_obj_set_style_bg_color(target, lv_palette_main(LV_PALETTE_RED), 0);
}
/**
* Demonstrate event bubbling
*/
void lv_example_event_3(void)
{
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);
uint32_t 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);
lv_label_set_text_fmt(label, "%"LV_PRIu32, i);
lv_obj_center(label);
}
lv_obj_add_event_cb(cont, event_cb, LV_EVENT_CLICKED, NULL);
}
#endif
def event_cb(e):
# The original target of the event. Can be the buttons or the container
target = e.get_target()
# print(type(target))
# If container was clicked do nothing
if type(target) != type(lv.btn()):
return
# Make the clicked buttons red
target.set_style_bg_color(lv.palette_main(lv.PALETTE.RED), 0)
#
# Demonstrate event bubbling
#
cont = lv.obj(lv.scr_act())
cont.set_size(320, 200)
cont.center()
cont.set_flex_flow(lv.FLEX_FLOW.ROW_WRAP)
for i in range(30):
btn = lv.btn(cont)
btn.set_size(80, 50)
btn.add_flag(lv.obj.FLAG.EVENT_BUBBLE)
label = lv.label(btn)
label.set_text(str(i))
label.center()
cont.add_event_cb(event_cb, lv.EVENT.CLICKED, None)