文章目錄
- 🧱 一、什么是 LVGL 事件?
- 🎯 二、事件回調的注冊
- 參數解釋:
- 示例:
- 📚 三、常見事件類型(`lv_event_code_t`)
- ? 1. 輸入類事件(用戶交互)
- ? 2. 組件狀態類事件
- ? 3. 生命周期類事件
- ? 4. 滾動與拖動類事件
- ?? 四、事件回調函數結構
- 🧪 五、完整示例:按鈕點擊顯示消息
- 🧠 六、LVGL 事件的高級用法
- ? 一次處理多個事件
- ? 使用用戶數據傳參
- 📌 總結
在 LVGL(Light and Versatile Graphics Library) 中,事件系統 是控件間交互的核心機制。它讓你能響應按鈕點擊、滑動、值變化、焦點獲取等各種行為。
我們來系統性地講解:
🧱 一、什么是 LVGL 事件?
事件(lv_event_t
)是 LVGL 中 控件生命周期或用戶操作引發的動作通知。
控件通過事件系統通知外部“某件事發生了”,我們通過注冊回調函數處理這些事件,完成邏輯響應。
比如:
- 按鈕被點擊(點擊事件)
- 滾動條滾動(值改變事件)
- 對象被刪除(清理事件)
🎯 二、事件回調的注冊
事件處理函數的注冊使用 lv_obj_add_event_cb()
函數:
lv_obj_add_event_cb(obj, my_event_cb, LV_EVENT_CLICKED, user_data);
參數解釋:
obj
:要監聽的對象my_event_cb
:事件回調函數(函數指針)LV_EVENT_CLICKED
:要監聽的事件類型user_data
:用戶自定義數據指針,會傳給回調(可為NULL
)
示例:
void my_event_cb(lv_event_t * e)
{lv_event_code_t code = lv_event_get_code(e);lv_obj_t * target = lv_event_get_target(e);if (code == LV_EVENT_CLICKED) {printf("Button clicked!\n");}
}
📚 三、常見事件類型(lv_event_code_t
)
LVGL 的事件可以分為幾類:
? 1. 輸入類事件(用戶交互)
事件宏 | 描述 |
---|---|
LV_EVENT_PRESSED | 用戶按下對象(觸摸/點擊) |
LV_EVENT_PRESSING | 按住過程中 |
LV_EVENT_PRESS_LOST | 按住但滑出控件范圍 |
LV_EVENT_RELEASED | 用戶釋放了對象 |
LV_EVENT_CLICKED | 完整的一次點擊(按下+釋放) |
LV_EVENT_LONG_PRESSED | 長按觸發 |
LV_EVENT_LONG_PRESSED_REPEAT | 長按后重復觸發 |
? 2. 組件狀態類事件
事件宏 | 描述 |
---|---|
LV_EVENT_FOCUSED | 控件獲取焦點 |
LV_EVENT_DEFOCUSED | 控件失去焦點 |
LV_EVENT_VALUE_CHANGED | 控件的值發生變化(如 slider) |
? 3. 生命周期類事件
事件宏 | 描述 |
---|---|
LV_EVENT_DRAW_MAIN_BEGIN/END | 繪制開始/結束(自定義繪制用) |
LV_EVENT_DELETE | 控件即將被刪除 |
LV_EVENT_CHILD_CHANGED | 子對象添加/刪除 |
? 4. 滾動與拖動類事件
事件宏 | 描述 |
---|---|
LV_EVENT_SCROLL_BEGIN | 開始滾動 |
LV_EVENT_SCROLL_END | 滾動停止 |
LV_EVENT_SCROLL | 正在滾動 |
LV_EVENT_SCROLL_DRAW_BEGIN/END | 滾動繪制開始/結束 |
?? 四、事件回調函數結構
void my_event_cb(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) {printf("Clicked: %s\n", lv_obj_get_style_text(obj, LV_PART_MAIN));}
}
🧪 五、完整示例:按鈕點擊顯示消息
void btn_event_cb(lv_event_t * e)
{lv_event_code_t code = lv_event_get_code(e);lv_obj_t * btn = lv_event_get_target(e);if(code == LV_EVENT_CLICKED) {printf("按鈕被點擊了!\n");lv_obj_t * label = lv_obj_get_child(btn, 0);lv_label_set_text(label, "已點擊!");}
}void create_btn()
{lv_obj_t * btn = lv_btn_create(lv_scr_act());lv_obj_center(btn);lv_obj_t * label = lv_label_create(btn);lv_label_set_text(label, "點我");lv_obj_center(label);lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_CLICKED, NULL);
}
🧠 六、LVGL 事件的高級用法
? 一次處理多個事件
lv_obj_add_event_cb(obj, my_cb, LV_EVENT_ALL, NULL);
然后在 my_cb
里判斷 code
即可。
? 使用用戶數據傳參
struct {int count;const char * msg;
} my_data = {0, "點擊次數"};lv_obj_add_event_cb(obj, my_cb, LV_EVENT_CLICKED, &my_data);
在回調中獲取:
void * data = lv_event_get_user_data(e);
📌 總結
LVGL 的事件系統 = 控件行為通知機制:
lv_obj_add_event_cb()
注冊回調;lv_event_t
是事件容器;lv_event_get_code()
獲取事件類型;- 支持交互、生命周期、繪圖等多個事件維度;
- 能通過用戶數據傳遞自定義信息。