LVGL 控件之矩阵按钮(lv_buttonmatrix)


一、矩阵按键

1、组成

按钮矩阵部件由两个部分组成:主体背景和按钮,示意图如下:

  • LV_PART_MAIN:对应按钮矩阵的背景
  • LV_PART_ITEMS:对应按钮矩阵的按钮
lv_obj_set_style_bg_color(btnM, lv_color_make(152, 244, 123), LV_PART_MAIN);

lv_obj_set_style_bg_color(btnM, lv_color_make(152, 244, 123), LV_PART_ITEMS);

2、创建矩阵

按钮矩阵部件中的每个按钮都可以设置文本,如果用户想设置这些按钮文本,则需要定义一个字符串数组(指针),并在该数组中传入所需的文本内容,最后通过 lv_btnmatrix_set_map 函数设置按钮文本,示例代码如下:

注意:该数组最后一个元素必须为空

lv_obj_t *btnM = lv_btnmatrix_create(lv_scr_act());
static const char* btnMap[] = {
    ",", "ABC", "DEF", "\n",
    "GHI", "JKL", "MNO", "\n",
    "PQRS", "TUV", "WXYX", ""
};
lv_btnmatrix_set_map(btnM, btnMap);
lv_obj_align(btnM, LV_ALIGN_CENTER, 0, 0);

此外,每个按钮还有个索引,索引对于按钮的属性设置非常重要。实际上索引的顺序就是我们添加按键的顺序:

3、按钮宽度

在默认情况下,按钮矩阵每一行按钮的宽度都是自动计算的,如果用户想改变按钮的宽度,可以调用 lv_btnmatrix_set_btn_width 函数来进行设置。值得注意的是,在按钮矩阵部件中,按钮只能设置相对宽度。

现在在上例的基础上添加:

lv_btnmatrix_set_btn_width(btnM, 1, 10);

4、按键属性

用户可以调用 lv_btnmatrix_set_btn_ctrl 函数,为按钮添加、清除指定的属性,这些属性的相关枚举如下:

  • LV_BTNMATRIX_CTRL_HIDDEN:将按钮隐藏;
  • LV_BTNMATRIX_CTRL_NO_REPEAT:禁用长按;
  • LV_BTNMATRIX_CTRL_DISABLED:禁用按钮;
  • LV_BTNMATRIX_CTRL_CHECKABLE:启用按钮状态切换;
  • LV_BTNMATRIX_CTRL_CHECKED:选中按钮;
  • LV_BTNMATRIX_CTRL_POPOVER:按下此按钮时在弹出窗口中显示按钮标签;
  • LV_BTNMATRIX_CTRL_RECOLOR:启用按钮文本的重新着色功能。

例:

lv_btnmatrix_set_btn_ctrl(btnM, 0, LV_BTNMATRIX_CTRL_HIDDEN);
lv_btnmatrix_set_btn_ctrl(btnM, 1, LV_BTNMATRIX_CTRL_DISABLED);
lv_btnmatrix_set_btn_ctrl(btnM, 2, LV_BTNMATRIX_CTRL_CHECKABLE);


如果用户想要清除按钮的指定属性,可以调用 lv_btnmatrix_clear_btn_ctrl 函数。

5、按钮互斥

按钮互斥是指:在某一时刻,只允许有一个按钮处于按下不弹起状态(被选中),当我们选中一个按钮之后,其他的按钮将会自动清除选中属性,示意图如下:

lv_btnmatrix_set_btn_ctrl(btnM, 0, LV_BTNMATRIX_CTRL_CHECKABLE);
lv_btnmatrix_set_btn_ctrl(btnM, 1, LV_BTNMATRIX_CTRL_CHECKABLE);
lv_btnmatrix_set_btn_ctrl(btnM, 2, LV_BTNMATRIX_CTRL_CHECKABLE);

lv_btnmatrix_set_one_checked(btnm1, true);

点击第一个键后,其处于被选中状态;


现在再点击第三个键,其处于被选中状态,不过第一个键的状态被清除了:

在这里插入图片描述

6、按钮文本重着色

在默认情况下,按钮矩阵中的按钮文本都是黑色的,如果用户需要设置文本为其他的颜色,则必须先调用 lv_btnmatrix_set_btn_ctrl 函数,为按钮添加文本重着色的属性。

设置如下:

void my_gui(void)
{
    lv_obj_t *btnM = lv_btnmatrix_create(lv_scr_act());
    static const char* btnMap[] = {
        ",", "#FF0000 ABC#", "DEF", "\n",
        "GHI", "JKL", "MNO", "\n",
        "PQRS", "TUV", "WXYX", ""
    };
    lv_btnmatrix_set_map(btnM, btnMap);
    lv_obj_align(btnM, LV_ALIGN_CENTER, 0, 0);

    lv_btnmatrix_set_btn_ctrl(btnM, 1, LV_BTNMATRIX_CTRL_RECOLOR);
}


注意看,颜色设置格式为:# + 16 进制颜色 + 按钮文本 + #,在设置完文本颜色之后,我们还需要为按钮添加文本重着色的属性,其相关的枚举为 LV_BTNMATRIX_CTRL_RECOLOR

7、按钮矩阵部件的事件

  1. LV_EVENT_VALUE_CHANGED:当一个按钮被按下、释放或长按时发送。
  2. LV_EVENT_DRAW_PART_BEGIN:开始绘制按钮。

8、API 函数

函数含义
lv_btnmatrix_create()创建按钮矩阵部件
lv_btnmatrix_set_map()设置按钮
lv_btnmatrix_set_ctrl_map()设置多个按钮属性
lv_btnmatrix_set_selected_btn()设置选中的按钮
lv_btnmatrix_set_btn_ctrl()设置一个按钮的属性
lv_btnmatrix_clear_btn_ctrl()清除某个按钮的属性
lv_btnmatrix_set_btn_ctrl_all()设置所有按钮的属性
lv_btnmatrix_clear_btn_ctrl_all()清除所有按钮的属性
lv_btnmatrix_set_btn_width()设置单个按钮的相对宽度
lv_btnmatrix_set_one_checked()设置按钮互斥
lv_btnmatrix_get_map()获取按钮相关映射
lv_btnmatrix_get_selected_btn()获取用户最后点击的按钮的索引
lv_btnmatrix_get_btn_text()获取按钮的文本
lv_btnmatrix_has_btn_ctrl()获取按钮的状态
lv_btnmatrix_get_one_checked()判断按钮互斥是否开启

二、例程

// 按键矩阵的事件回调函数
static void btnmatrix_event_callback(lv_event_t * event)
{
    if (event == NULL)
    {
        printf("[%s:%d] event is NULL\n", __FUNCTION__, __LINE__);
        return ;
    }

    lv_event_code_t code = lv_event_get_code(event); // 获取当前event的code
    lv_obj_t * obj = lv_event_get_target(event);     // 获取当前事件的触发对象

    if (code == LV_EVENT_DRAW_PART_BEGIN) // 开始绘制一个区域的事件,这个事件的参数是lv_obj_draw_part_dsc_t *
    {
        lv_obj_draw_part_dsc_t * dsc = (lv_obj_draw_part_dsc_t *)lv_event_get_param(event);
        if (dsc != NULL)
        {
            switch (dsc->id)
            {
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                case 6:
                case 7:
                case 8:
                case 9:
                case 10:
                case 11:
                    {
                        if (lv_btnmatrix_get_selected_btn(obj) == dsc->id)
                        {
                            if (dsc->rect_dsc != NULL)
                            {
                                // 设置目标绘制区域的背景颜色
                                dsc->rect_dsc->bg_color = lv_color_hex(0xFF6008); // 橙色
                            }
                        }
                        else
                        {
                            if (dsc->rect_dsc != NULL)
                            {
                                dsc->rect_dsc->bg_color = lv_color_hex(0xF98E2D);
                            }
                        }

                        if (dsc->rect_dsc != NULL)
                        {
                            dsc->rect_dsc->radius = 5; // 设置目标绘制区域的圆角
                            dsc->rect_dsc->border_width = 0; // 设置目标绘制区域的边框宽度
                            dsc->rect_dsc->shadow_ofs_x = 0; // 在X方向的像素上设置阴影的偏移量
                            dsc->rect_dsc->shadow_ofs_y = 0; // 在Y方向的像素上设置阴影的偏移量
                         }

                         if (dsc->label_dsc != NULL)
                         {
                            dsc->label_dsc->color = lv_color_hex(0xFFFFFF);
                         }
                    }
                    break;

                default:
                    break;
            }
        }
    }
    else if(code == LV_EVENT_VALUE_CHANGED) // 当一个按钮被按下、释放或长按时
    {
        lv_obj_t * text_area = (lv_obj_t *)lv_event_get_user_data(event); // 获取事件的user_data
        uint16_t btn_id = lv_btnmatrix_get_selected_btn(obj);             // 获取当前选中的按键的id
        const char * txt = lv_btnmatrix_get_btn_text(obj, btn_id);        // 获取当前按键的文本

        if (txt != NULL)
        {
            if (strcmp(txt, LV_SYMBOL_BACKSPACE) == 0)
            {
                if (text_area != NULL)
                {
                    lv_textarea_del_char(text_area); // 删除文本框的字符
                }
            }
            else
            {
                if (text_area != NULL)
                {
                    lv_textarea_add_text(text_area, txt); // 文本框追加字符
                }
            }
        }
    }
}


void my_gui()
{
    static const char * btnm_map[] = {"1", "2", "3", "\n",
                                       "4", "5", "6", "\n",
                                       "7", "8", "9", "\n",
                                       ".", "0", LV_SYMBOL_BACKSPACE, ""};

    lv_obj_t * obj_text_area = lv_textarea_create(lv_scr_act()); // 创建文本框控件
    if (obj_text_area == NULL)
    {
        printf("[%s:%d] obj_text_area is NULL\n", __FUNCTION__, __LINE__);
        return ;
    }

    lv_textarea_set_one_line(obj_text_area, true);        // 将文本区域配置为一行
    lv_textarea_set_password_mode(obj_text_area, true);   // 将文本区域配置为密码模式
    lv_textarea_set_max_length(obj_text_area, 15);        // 设置文本区域可输入的字符长度最大值
    lv_obj_add_state(obj_text_area, LV_STATE_FOCUSED);    // 显示光标
    lv_obj_set_style_radius(obj_text_area, 5, 0);         // 设置样式的圆角弧度
    lv_obj_set_style_border_width(obj_text_area, 1, 0);   //设置边框宽度
    lv_obj_set_size(obj_text_area, 255, 40);              // 设置对象大小
    lv_obj_align(obj_text_area, LV_ALIGN_TOP_MID, 0, 50);

    lv_obj_t * obj_btnm = lv_btnmatrix_create(lv_scr_act()); // 创建一个按钮矩阵对象
    if (obj_btnm == NULL)
    {
        printf("[%s:%d] obj_btnm is NULL\n", __FUNCTION__, __LINE__);
        return ;
    }

    lv_btnmatrix_set_one_checked(obj_btnm, true);  // 启用“一次检查”功能,允许一次只检查一个按钮。
    lv_obj_set_size(obj_btnm, 260, 245);           // 设置控件大小
    lv_obj_align(obj_btnm, LV_ALIGN_CENTER, 0, 0);
    lv_obj_clear_flag(obj_btnm, LV_OBJ_FLAG_CLICK_FOCUSABLE); // 按钮按下的是时候焦点才聚集到该控件,确保按钮按下后焦点聚集到文本框
    lv_btnmatrix_set_map(obj_btnm, btnm_map);                 // 给按钮矩阵添加键盘映射

    int i = 0;
    for (i = 0; i < 12; i++)
    {
        lv_btnmatrix_set_btn_ctrl(obj_btnm, i, LV_BTNMATRIX_CTRL_NO_REPEAT); // 长按按钮时禁用重复
    }

    lv_obj_set_style_radius(obj_btnm, 0, 0);                                                       // 设置样式的圆角弧度
    lv_obj_set_style_border_width(obj_btnm, 0, 0);                                                 //设置边框宽度
    lv_obj_set_style_bg_color(obj_btnm, lv_color_hex(0xFFFFFF), 0);                                // 设置背景颜色
    lv_obj_set_style_bg_opa(obj_btnm, LV_OPA_0, 0);                                                // 设置样式背景的不透明度
    lv_obj_set_style_text_font(obj_btnm, &lv_font_montserrat_20, 0);                               //设置字体
    lv_obj_add_event_cb(obj_btnm, btnmatrix_event_callback, LV_EVENT_ALL, (void *)obj_text_area);  // 按钮矩阵添加事件回调函数
}
  • 26
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个基于LVGL V7的`lv_textarea`控件的示例代码,它包括按键响应处理和关闭控件功能。你可以将这段代码添加到你的项目中,然后根据需要进行修改。 ```c #include "lvgl/lvgl.h" /* 定义一个lv_textarea控件 */ static lv_obj_t * textarea; /* 按键事件回调函数 */ static lv_res_t btn_click_action(lv_obj_t * btn) { /* 获取按钮的标签 */ const char * btn_label = lv_btn_get_state_text(btn, LV_BTN_STATE_RELEASED); /* 检查按钮标签 */ if(strcmp(btn_label, "关闭") == 0) { /* 隐藏lv_textarea控件 */ lv_obj_set_hidden(textarea, true); } else if(strcmp(btn_label, "保存") == 0) { /* 获取lv_textarea控件的文本 */ const char * text = lv_textarea_get_text(textarea); /* 打印文本 */ printf("textarea text: %s\r\n", text); } return LV_RES_OK; } void lv_textarea_example(void) { /* 创建一个容器 */ lv_obj_t * container = lv_cont_create(lv_scr_act(), NULL); lv_cont_set_fit(container, LV_FIT_TIGHT); /* 创建一个lv_textarea控件 */ textarea = lv_textarea_create(container, NULL); lv_obj_set_size(textarea, 200, 100); lv_textarea_set_text(textarea, "Hello, LVGL!"); lv_textarea_set_cursor_hidden(textarea, true); /* 创建一个关闭按钮 */ lv_obj_t * close_btn = lv_btn_create(container, NULL); lv_btn_set_state_text(close_btn, LV_BTN_STATE_RELEASED, "关闭"); lv_obj_set_event_cb(close_btn, btn_click_action); /* 创建一个保存按钮 */ lv_obj_t * save_btn = lv_btn_create(container, NULL); lv_btn_set_state_text(save_btn, LV_BTN_STATE_RELEASED, "保存"); lv_obj_set_event_cb(save_btn, btn_click_action); /* 设置容器布局 */ lv_cont_set_layout(container, LV_LAYOUT_COLUMN_MID); /* 设置关闭按钮和保存按钮的位置 */ lv_cont_set_fit2(close_btn, LV_FIT_NONE, LV_FIT_TIGHT); lv_cont_set_fit2(save_btn, LV_FIT_NONE, LV_FIT_TIGHT); /* 设置关闭按钮和保存按钮之间的间隔 */ lv_obj_set_style_pad_right(close_btn, 10, 0); } ``` 在这个示例代码中,我们创建了一个容器,并在其中创建了一个`lv_textarea`控件和两个按钮。在关闭按钮被点击时,我们将隐藏`lv_textarea`控件;在保存按钮被点击时,我们将获取`lv_textarea`控件的文本,并将其打印出来。 需要注意的是,这个示例代码中的按钮事件回调函数`btn_click_action`仅用于演示。在实际应用中,你需要根据需要修改按钮事件回调函数的实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值