LVGL回调函数知识体系

一、回调函数基础体系

1. 回调函数本质
// 典型LVGL回调函数原型
typedef void (*lv_event_cb_t)(lv_event_t * e);

// 事件结构体关键成员
struct _lv_event_t {
    lv_obj_t * target;    // 触发事件的对象
    lv_obj_t * current_target; // 当前处理对象
    lv_event_code_t code; // 事件类型
    void * user_data;     // 用户自定义数据
};
2. 基础绑定方式
// 案例1:按钮点击回调
lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_CLICKED, NULL);

void btn_event_cb(lv_event_t * e) {
    if(lv_event_get_code(e) == LV_EVENT_CLICKED) {
        AmbaPrint("按钮被点击");
    }
}

二、事件传递机制

1. 事件冒泡(Bubbling)

// 案例2:阻止事件冒泡
void child_event_cb(lv_event_t * e) {
    lv_event_stop_bubbling(e); // 停止向上传递
}
2. 事件标记(Event Marks)
// 案例3:标记已处理事件
lv_obj_add_event_cb(obj, event_cb, LV_EVENT_ALL, NULL);

void event_cb(lv_event_t * e) {
    if(lv_event_get_code(e) == LV_EVENT_PRESSED) {
        lv_obj_add_state(obj, LV_STATE_PRESSED);
        lv_event_mark_stop(e); // 标记为已处理
    }
}

三、用户数据传递

1. 静态数据传递
// 案例4:传递整型参数
int param = 42;
lv_obj_add_event_cb(btn, event_cb, LV_EVENT_CLICKED, (void*)param);

void event_cb(lv_event_t * e) {
    int received = (int)lv_event_get_user_data(e);
    AmbaPrint("收到参数: %d", received);
}
2. 动态数据传递
// 案例5:传递结构体(需内存管理)
typedef struct {
    int id;
    char name[20];
} MyData;

MyData *data = lv_mem_alloc(sizeof(MyData));
lv_obj_add_event_cb(obj, event_cb, LV_EVENT_ALL, data);

void event_cb(lv_event_t * e) {
    if(lv_event_get_code(e) == LV_EVENT_DELETE) {
        lv_mem_free(lv_event_get_user_data(e));
    }
}

四、手动触发事件

1. 基础触发方式
// 案例6:手动发送点击事件
lv_event_send(btn, LV_EVENT_CLICKED, NULL);

// 案例7:带参数触发
int value = 100;
lv_event_send(slider, LV_EVENT_VALUE_CHANGED, &value);
2. 自定义事件
// 定义自定义事件码(建议>1024)
#define LV_EVENT_MY_CUSTOM  (LV_EVENT_LAST + 1)

// 案例8:发送与接收
lv_event_send(obj, LV_EVENT_MY_CUSTOM, "Hello");

void event_cb(lv_event_t * e) {
    if(lv_event_get_code(e) == LV_EVENT_MY_CUSTOM) {
        char* msg = (char*)lv_event_get_param(e);
        AmbaPrint("自定义消息: %s", msg);
    }
}

五、高级应用模式

1. 事件代理模式
// 案例9:集中处理多个对象事件
void register_buttons(lv_obj_t * parent) {
    for(int i=0; i<3; i++) {
        lv_obj_t * btn = lv_btn_create(parent);
        lv_obj_add_event_cb(btn, button_delegate, LV_EVENT_ALL, (void*)i);
    }
}

void button_delegate(lv_event_t * e) {
    int btn_id = (int)lv_event_get_user_data(e);
    switch(lv_event_get_code(e)) {
        case LV_EVENT_CLICKED: 
            AmbaPrint("按钮%d被点击", btn_id);
            break;
    }
}
2. 状态机模式
// 案例10:基于事件的UI状态管理
typedef enum {
    STATE_IDLE,
    STATE_ACTIVE,
    STATE_ERROR
} AppState;

void state_machine_cb(lv_event_t * e) {
    static AppState state = STATE_IDLE;
    
    switch(state) {
        case STATE_IDLE:
            if(lv_event_get_code(e) == LV_EVENT_PRESSED) {
                state = STATE_ACTIVE;
                update_ui_state();
            }
            break;
        // 其他状态处理...
    }
}

六、实战项目案例

案例11:智能家居控制面板
// 场景:多房间灯光控制
typedef struct {
    uint8_t room_id;
    lv_obj_t * switch_obj;
    lv_obj_t * brightness_slider;
} RoomControl;

void init_room_controls() {
    RoomControl * living_room = lv_mem_alloc(sizeof(RoomControl));
    living_room->room_id = 1;
    
    living_room->switch_obj = lv_switch_create(lv_scr_act());
    lv_obj_add_event_cb(living_room->switch_obj, room_switch_cb, LV_EVENT_ALL, living_room);
}

void room_switch_cb(lv_event_t * e) {
    RoomControl * room = (RoomControl *)lv_event_get_user_data(e);
    
    if(lv_event_get_code(e) == LV_EVENT_VALUE_CHANGED) {
        bool is_on = lv_obj_has_state(room->switch_obj, LV_STATE_CHECKED);
        mqtt_publish("home/light/%d", room->room_id, is_on);
        
        // 手动更新亮度滑块状态
        lv_obj_set_enabled(room->brightness_slider, is_on);
    }
}
案例12:工业仪表盘
// 场景:实时数据更新
void data_update_timer_cb(lv_timer_t * timer) {
    static int count = 0;
    lv_obj_t * gauge = (lv_obj_t *)timer->user_data;
    
    // 模拟数据更新
    int new_value = rand() % 100;
    lv_gauge_set_value(gauge, 0, new_value);
    
    // 超过阈值触发告警事件
    if(new_value > 80) {
        lv_event_send(gauge, LV_EVENT_ALARM_TRIGGERED, &new_value);
    }
}

void gauge_event_cb(lv_event_t * e) {
    if(lv_event_get_code(e) == LV_EVENT_ALARM_TRIGGERED) {
        int * value = (int*)lv_event_get_param(e);
        AmbaPrint("警报!当前值: %d", *value);
        lv_obj_add_state(gauge, LV_STATE_ERROR);
    }
}

七、调试与优化

1. 事件调试技巧
// 打印事件信息
void debug_event_cb(lv_event_t * e) {
    AmbaPrint("事件[0x%x]来自对象%p", 
             lv_event_get_code(e),
             lv_event_get_target(e));
}

// 绑定到测试对象
lv_obj_add_event_cb(test_obj, debug_event_cb, LV_EVENT_ALL, NULL);
2. 性能优化
// 案例13:事件节流
static uint32_t last_event_time = 0;

void throttle_event_cb(lv_event_t * e) {
    uint32_t now = lv_tick_get();
    if(now - last_event_time < 200) return; // 200ms内不重复处理
    
    last_event_time = now;
    // 实际处理逻辑...
}

知识体系总结

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爬爬pua

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值