lvgl 笔记 按钮部件 (lv_btn) 和 开关部件 (lv_switch)

本文介绍了LVGL图形库中按钮和开关的基础用法,包括创建、设置大小位置、添加样式、响应事件以及状态检查。还展示了如何通过事件回调实现互斥锁功能,确保同一时间只有一个开关处于选中状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

按钮基础使用方法:

lv_btn lb_obj 使用方法一样,只是外表并不相同,基础创建方法只需一行代码。

lv_obj_t* btn = lv_btn_create(lv_scr_act());

添加大小和位置: 

lv_obj_t* btn = lv_btn_create(lv_scr_act());
lv_obj_set_size(btn, 100, 50);
lv_obj_set_align(btn, LV_ALIGN_CENTER);

添加触发样式: 

lv_obj_set_style_bg_color() 配置为,LV_STATE_PRESSED 即可配置为按下改变颜色。

其中和 lv_obj 一样,共有以下可供选择的参数:

lv_obj_t* btn = lv_btn_create(lv_scr_act());
lv_obj_set_size(btn, 100, 50);
lv_obj_set_align(btn, LV_ALIGN_CENTER);
lv_obj_set_style_bg_color(btn, lv_color_hex(0xffe1d4), LV_STATE_PRESSED);

添加事件:

lv_obj_add_event_cb(); 可以添加事件。

static void event_cb(lv_event_cb_t* e) {
    lv_event_code_t code = lv_event_get_code(e);
    if (code == LV_EVENT_VALUE_CHANGED) {
        printf("LV_EVENT_VALUE_CHANGED\n");
    }
}

void my_gui(void){
    lv_obj_t* btn = lv_btn_create(lv_scr_act());
    lv_obj_add_flag(btn, LV_OBJ_FLAG_CHECKABLE);
    lv_obj_add_event_cb(btn, event_cb, LV_EVENT_VALUE_CHANGED, NULL);
}

开关基础使用方法:

lv_obj_t* switch1 = lv_switch_create(lv_scr_act());

为开关部件配置颜色:

开关部件共有三个部分可以单独配置颜色,主体是指未被选中状态(下图中灰色),手柄指的是圆球部分,指示器则是选中部分(下图中蓝色)。

    lv_obj_t* switch1 = lv_switch_create(lv_scr_act());
    lv_obj_set_style_bg_color(switch1, lv_color_hex(0xea1b1b), LV_PART_MAIN);
    lv_obj_set_pos(switch1, 0, 0);

    lv_obj_t* switch2 = lv_switch_create(lv_scr_act());
    lv_obj_set_style_bg_color(switch2, lv_color_hex(0xea1b1b),LV_PART_KNOB);
    lv_obj_set_pos(switch2, 0, 50);

    lv_obj_t* switch3 = lv_switch_create(lv_scr_act());
    lv_obj_set_style_bg_color(switch3, lv_color_hex(0xea1b1b), LV_STATE_CHECKED|LV_PART_INDICATOR);
    lv_obj_set_pos(switch3, 0, 100);

 

 值得注意的是,在设置 LV_PART_INDICATOR 指示器时,完整的写法应与上 LV_STATE_CHECKED,不然配置的样式就会被覆盖,导致不生效。

 lv_obj_set_style_bg_color(switch3, lv_color_hex(0xea1b1b), LV_STATE_CHECKED|LV_PART_INDICATOR);

修改开关状态:

按钮状态默认是关闭的,如果我们使用 lv_obj_add_state() 函数即可为按钮添加一个选中的状态,这样他在第一次运行时就是打开状态。

lv_obj_t* switch1 = lv_switch_create(lv_scr_act());
lv_obj_set_pos(switch1, 0, 0);

lv_obj_t* switch2 = lv_switch_create(lv_scr_act());
lv_obj_add_state(switch2, LV_STATE_CHECKED);
lv_obj_set_pos(switch2, 0, 50);

 如果要让按钮不被选中,我们可以再移除这个状态:lv_obj_clear_state() 即可做到

lv_obj_clear_state(switch2, LV_STATE_CHECKED);

 除了修改 LV_STATE_CHECKED 状态外,另一个 LV_STATE_DISABLED 状态也经常使用,他的作用的使得按钮不能被修改。

捕捉按钮状态:

lv_obj_has_state() 函数可以返回当前组件的状态。在以下代码中,我们使用了:

lv_obj_has_state(switch1, LV_STATE_CHECKED)

来返回选中状态。其原理是检查 LV_STATE_CHECKED 的状态判断的。

static void event_cb(lv_event_t* e) {
    lv_event_code_t code = lv_event_get_code(e);
    if (lv_obj_has_state(switch1, LV_STATE_CHECKED)) {
        printf("LED ON \n");
    }
    else {
        printf("LED OFF \n");
    }
}

void my_gui(void) {
    switch1 = lv_switch_create(lv_scr_act());
    lv_obj_add_event_cb(switch1, event_cb, LV_EVENT_VALUE_CHANGED, NULL); //对象的值改变即触发回调
}

效果如下: 

互斥锁案例:

static void event_cb(lv_event_t* e) {
    lv_obj_t* target = lv_event_get_target(e); //获得触发的基本对象

    if (target == switch1) {
        if (lv_obj_has_state(switch1, LV_STATE_CHECKED)) 
            lv_obj_clear_state(switch2, LV_STATE_CHECKED);
        else 
            lv_obj_add_state(switch2, LV_STATE_CHECKED);
    }

    if (target == switch2) {
        if (lv_obj_has_state(switch2, LV_STATE_CHECKED)) 
            lv_obj_clear_state(switch1, LV_STATE_CHECKED);
        else 
            lv_obj_add_state(switch1, LV_STATE_CHECKED);
    }
}

void my_gui(void) {
    switch1 = lv_switch_create(lv_scr_act());
    lv_obj_add_event_cb(switch1, event_cb, LV_EVENT_VALUE_CHANGED, NULL);

    switch2 = lv_switch_create(lv_scr_act());
    lv_obj_add_state(switch2, LV_STATE_CHECKED);
    lv_obj_set_pos(switch2, 0, 50);
    lv_obj_add_event_cb(switch2, event_cb, LV_EVENT_VALUE_CHANGED, NULL);
}

 原理是当设置了一个按钮之后,就对另一个按钮通过配置 lv_obj_add_state() 和 lv_obj_clear_state() 做出与之相反的动作。

 

这段代码是一个基于 **LVGL** 图形库的 JavaScript 扩展函数,用于从列表组件 (`lv_obj_t`) 中获取当前处于聚焦状态(`LV_STATE_FOCUSED`)的按钮,并将其包装成一个可以返回给 JavaScript 环境的对象。 以下是逐步解析: --- ### 函数功能描述 1. **声明与入口** ```c DECLARE_HANDLER(getBtnSelected) ``` 这段代码通过宏 `DECLARE_HANDLER` 声明了一个名为 `getBtnSelected` 的处理函数。它可能是某个框架提供的机制,用于将 C/C++ 功能暴露到 JavaScript 引擎环境中运行。 2. **获取列表对象** ```c lv_obj_t *list = get_lvgl_from_jsclass_obj(ctx, this_value, js_list_class_id); ``` - 调用了 `get_lvgl_from_jsclass_obj()` 函数。 - 参数解释: - `ctx`: 当前上下文环境。 - `this_value`: 表示当前调用者的实例。 - `js_list_class_id`: 指定这是一个 List 类型的绑定标识符。 - 目标是从 JavaScript 对象中提取出对应的 LVGL 列表控件(`lv_obj_t* list`),这是后续操作的核心数据结构。 3. **遍历子元素** ```c int chlid_cnt = lv_obj_get_child_cnt(list); // 获取所有子节点的数量 for (int i = 0; i < chlid_cnt; i++) { // 遍历每个子节点 lv_obj_t *tmp_btn = lv_obj_get_child(list, i); // 取第i个子对象 if (tmp_btn && lv_obj_has_state(tmp_btn, LV_STATE_FOCUSED)) { btn = tmp_btn; break; // 如果找到已选中的按钮,则停止搜索 } } ``` - 使用了 `lv_obj_get_child_cnt()` `lv_obj_get_child()` 来逐一遍历列表的所有子项。 - 检查每一个子对象是否处于“聚焦”状态(`LV_STATE_FOCUSED`)。如果找到了满足条件的第一个按钮,就记录下来并退出循环。 4. **封装结果** ```c if (btn) { return wrap_lvgl_to_jsclass_obj(ctx, btn, get_js_button_class()); } ``` - 如果成功找到了符合条件的按钮(`btn != NULL`),则使用 `wrap_lvgl_to_jsclass_obj()` 将其转换为可以在 JavaScript 中使用的对象形式。 - 最终返回该对象至调用者。 5. **默认值** ```c return JS_NULL; ``` - 如果未找到任何匹配的按钮,直接返回空指针(`JS_NULL`),表示没有选择的项目。 --- ### 总结作用 此函数的作用是从一个 LVGL 的列表控件中查找当前获得焦点的那个按钮,并将其作为可交互的 JavaScript 对象返回。如果没有合适的选项被选中,则返回空值。 --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值