以下是关于 lv_obj_add_event_cb()
函数的详细说明,适用于 LVGL 8.2 版本:
函数原型
lv_event_code_t lv_obj_add_event_cb(
lv_obj_t *obj, // 目标对象(如按钮、标签等)
lv_event_cb_t event_cb, // 事件回调函数
lv_event_code_t filter, // 监听的事件类型
void *user_data // 用户自定义数据(可选)
);
功能
为 LVGL 对象(如按钮、标签等)注册一个事件回调函数,用于处理特定事件(如点击、长按、拖动等)。
参数说明
参数 | 类型 | 说明 |
---|---|---|
obj | lv_obj_t * | 要绑定事件的对象(例如按钮、滑块等)。 |
event_cb | lv_event_cb_t | 事件回调函数,需定义为 static void func(lv_event_t *e) 。 |
filter | lv_event_code_t | 监听的事件类型(如 LV_EVENT_CLICKED ),或 LV_EVENT_ALL 监听所有事件。 |
user_data | void * | 用户自定义数据,可在回调函数中通过 lv_event_get_user_data(e) 获取(可选,传 NULL 忽略)。 |
事件类型(常用值)
事件类型 | 说明 |
---|---|
LV_EVENT_CLICKED | 点击事件(按下并释放)。 |
LV_EVENT_PRESSED | 按下事件(无需释放)。 |
LV_EVENT_LONG_PRESSED | 长按事件。 |
LV_EVENT_VALUE_CHANGED | 值改变事件(如滑块拖动)。 |
LV_EVENT_FOCUSED | 对象获得焦点。 |
LV_EVENT_DEFOCUSED | 对象失去焦点。 |
LV_EVENT_ALL | 监听所有事件。 |
完整事件列表见 LVGL 文档。
回调函数定义
回调函数必须为 静态函数(C 语言中无法使用 Lambda):
static void your_event_handler(lv_event_t *e) {
lv_event_code_t code = lv_event_get_code(e); // 获取事件类型
lv_obj_t *obj = lv_event_get_target(e); // 获取触发事件的对象
void *user_data = lv_event_get_user_data(e); // 获取用户数据
if(code == LV_EVENT_CLICKED) {
// 处理点击事件
}
}
使用示例
示例 1:处理按钮点击事件
// 定义回调函数
static void btn_click_handler(lv_event_t *e) {
if(lv_event_get_code(e) == LV_EVENT_CLICKED) {
lv_obj_t *btn = lv_event_get_target(e);
lv_label_set_text(user_data, "Clicked!"); // user_data 需提前传递
}
}
// 创建按钮并绑定事件
lv_obj_t *btn = lv_btn_create(lv_scr_act());
lv_obj_t *label = lv_label_create(btn);
lv_label_set_text(label, "Click Me");
// 绑定事件,将 label 作为用户数据传递
lv_obj_add_event_cb(btn, btn_click_handler, LV_EVENT_CLICKED, label);
示例 2:监听多个事件
// 监听按下和释放事件
lv_obj_add_event_cb(slider, slider_event_handler,
LV_EVENT_PRESSED | LV_EVENT_RELEASED, NULL);
// 回调函数中处理不同事件
static void slider_event_handler(lv_event_t *e) {
lv_event_code_t code = lv_event_get_code(e);
if(code == LV_EVENT_PRESSED) {
printf("Slider pressed\n");
} else if(code == LV_EVENT_RELEASED) {
printf("Slider released\n");
}
}
示例 3:传递结构体数据
typedef struct {
lv_obj_t *label;
int counter;
} my_data_t;
// 创建并初始化用户数据
my_data_t *data = malloc(sizeof(my_data_t));
data->label = lv_label_create(lv_scr_act());
data->counter = 0;
// 绑定事件,传递结构体
lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, data);
// 回调函数
static void event_handler(lv_event_t *e) {
my_data_t *data = lv_event_get_user_data(e);
data->counter++;
lv_label_set_text_fmt(data->label, "Count: %d", data->counter);
}
注意事项
- 静态函数:回调函数必须为
static
(C 语言限制)。 - 用户数据生命周期:
- 如果传递动态分配的内存(如
malloc
),需在对象删除时手动释放:lv_obj_add_event_cb(obj, delete_handler, LV_EVENT_DELETE, data); static void delete_handler(lv_event_t *e) { free(lv_event_get_user_data(e)); }
- 如果传递动态分配的内存(如
- 事件冲突:同一对象的多个回调函数按注册顺序执行。
- 性能:避免在频繁触发的事件(如
LV_EVENT_VALUE_CHANGED
)中执行耗时操作。
总结
通过 lv_obj_add_event_cb()
,您可以为 LVGL 对象实现交互逻辑。核心步骤:
- 定义静态回调函数。
- 绑定事件类型和用户数据。
- 在回调中通过
lv_event_get_code(e)
和lv_event_get_user_data(e)
处理事件。