LVGL学习笔记11 - 按钮矩阵Button Matrix

31 篇文章 83 订阅

目录

1. 构造矩阵

2. Parts

2.1 LV_PART_MAIN

2.2 LV_PART_ITEMS

3. 样式

3.1 按钮大小

3.2 间距

3.3 控制按钮

3.4 控制map

 3.5 Check唯一性

 4. 事件

4.1 LV_EVENT_VALUE_CHANGED

4.2 LV_EVENT_LONG_PRESSED

4.3 LV_EVENT_DRAW_PART_BEGIN


按钮矩阵是多个按钮的组合,例如直接绘制一个九宫格按键。按钮矩阵的按钮是实时绘制的,所以占用的内存会比较小。通过lv_btnmatrix_create函数创建按钮矩阵对象。 

static lv_obj_t *btnM = lv_btnmatrix_create(lv_scr_act());

1. 构造矩阵

通过一个称为map的描述符字符串数组来实现,每个字符串代表一个按钮,然后通过lv_btnmatrix_set_map设置这个map。

static 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);

map数组通过回车符换行,通过0表示结束,和字符串的定义一致。

2. Parts

按钮矩阵有2个Parts:LV_PART_MAIN和LV_PART_ITEMS。

2.1 LV_PART_MAIN

对应按钮矩阵的背景。

lv_obj_set_style_bg_color(btnM, lv_color_make(252, 144, 181), LV_PART_MAIN);

2.2 LV_PART_ITEMS

对应按钮矩阵的按钮。

lv_obj_set_style_bg_color(btnM, lv_color_make(252, 144, 181), LV_PART_ITEMS);

 

3. 样式

3.1 按钮大小

通过lv_btnmatrix_set_btn_width函数设置按钮大小。

void lv_btnmatrix_set_btn_width(lv_obj_t * obj, uint16_t btn_id, uint8_t width)

参数btn_id表示需要修改哪个按钮的宽度。

参数width和之前的宽度含义不同,不是以像素为单位,表示倍数的关系,有效值是1-7,设置为0时也是和1的设定一样。

lv_btnmatrix_set_btn_width(btnM, 0, 1);
lv_btnmatrix_set_btn_width(btnM, 3, 2);

对比上面2个设定(宽度为1和2的情况):

 

id为0和id为3的按钮被设置,可以看到id为0的按钮宽度还是1个单位宽度,而id为3的按钮宽度变为2个单位。注意这个单位宽度是当前x轴上平均宽度,比如上图第二行,总宽度是1,3个按钮分别的宽度是2/1/1,所以总宽度单位是4,1个单位宽度是25%,3个按钮分别占据50%,25%,25%。

3.2 间距

通过lv_obj_set_style_pad_row和lv_obj_set_style_pad_column可以调整按钮之间的间距。

void lv_obj_set_style_pad_row(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
void lv_obj_set_style_pad_column(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
lv_obj_set_style_pad_row(btnM, 2, LV_PART_MAIN);

lv_obj_set_style_pad_column(btnM, 2, LV_PART_MAIN);

 

另外可以通过lv_obj_set_style_pad_top,lv_obj_set_style_pad_bottom,lv_obj_set_style_pad_left和lv_obj_set_style_pad_right调整按钮和边界的距离。

3.3 控制按钮

 通过lv_btnmatrix_set_btn_ctrl设置按钮的控制形态,通过lv_btnmatrix_clear_btn_ctrl清除。

void lv_btnmatrix_set_btn_ctrl(lv_obj_t * obj, uint16_t btn_id, lv_btnmatrix_ctrl_t ctrl)
void lv_btnmatrix_clear_btn_ctrl(lv_obj_t * obj, uint16_t btn_id, lv_btnmatrix_ctrl_t ctrl)

通过lv_btnmatrix_set_btn_ctrl_all和lv_btnmatrix_clear_btn_ctrl_all设置所有按钮的控制形态。 

 控制形态的枚举,可以通过OR的方式多个控制

enum {
    _LV_BTNMATRIX_WIDTH     = 0x0007,      /**< Reserved to stire the size units*/
    LV_BTNMATRIX_CTRL_HIDDEN     = 0x0008, /**< Button hidden*/
    LV_BTNMATRIX_CTRL_NO_REPEAT  = 0x0010, /**< Do not repeat press this button.*/
    LV_BTNMATRIX_CTRL_DISABLED   = 0x0020, /**< Disable this button.*/
    LV_BTNMATRIX_CTRL_CHECKABLE  = 0x0040, /**< The button can be toggled.*/
    LV_BTNMATRIX_CTRL_CHECKED    = 0x0080, /**< Button is currently toggled (e.g. checked).*/
    LV_BTNMATRIX_CTRL_CLICK_TRIG = 0x0100, /**< 1: Send LV_EVENT_VALUE_CHANGE on CLICK, 0: Send LV_EVENT_VALUE_CHANGE on PRESS*/
    LV_BTNMATRIX_CTRL_POPOVER    = 0x0200, /**< Show a popover when pressing this key*/
    LV_BTNMATRIX_CTRL_RECOLOR    = 0x1000, /**< Enable text recoloring with `#color`*/
    _LV_BTNMATRIX_CTRL_RESERVED  = 0x2000, /**< Reserved for later use*/
    LV_BTNMATRIX_CTRL_CUSTOM_1   = 0x4000, /**< Custom free to use flag*/
    LV_BTNMATRIX_CTRL_CUSTOM_2   = 0x8000, /**< Custom free to use flag*/
};

LV_BTNMATRIX_CTRL_HIDDEN: 隐藏按钮。

LV_BTNMATRIX_CTRL_NO_REPEAT: 显示无区别,当长按时不重复按键事件。

LV_BTNMATRIX_CTRL_DISABLED:禁止按钮。蓝色圈不见了,点击不能选中。

LV_BTNMATRIX_CTRL_CHECKABLE: Check型按钮。

LV_BTNMATRIX_CTRL_CHECKED:按钮为选中状态,原则上需要和LV_BTNMATRIX_CTRL_CHECKABLE一起使用。

LV_BTNMATRIX_CTRL_CLICK_TRIG:和显示无关,表示按钮点击时在事件LV_EVENT_VALUE_CHANGE中发送1,按下时发送0.

LV_BTNMATRIX_CTRL_POPOVER:按键时弹出窗口。

LV_BTNMATRIX_CTRL_RECOLOR:启用文本可以通过‘#颜色’更改颜色。例如:

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

map中2个按钮写入了颜色的关键字,但是只启用了按钮3为改颜色。

3.4 控制map

和创建矩阵的map类似,设置控制属性时可以通过一个map直接设置所有的按钮。

   static const char* btnMap[] = {
        ",", "ABC", "DEF", "\n",
        "#FF0000 GHI", "JKL", "MNO", "\n",
        "PQRS", "TUV", "WXYX", ""
    };
    static const lv_btnmatrix_ctrl_t ctrlMap[] =
    {
        1 | LV_BTNMATRIX_CTRL_CHECKABLE, 1,  1,
        2 | LV_BTNMATRIX_CTRL_RECOLOR, 1, 1,
        1, 1, 1 | LV_BTNMATRIX_CTRL_POPOVER
    };
    lv_btnmatrix_set_map(btnM, btnMap);
    lv_btnmatrix_set_ctrl_map(btnM, ctrlMap);
    //lv_btnmatrix_set_btn_ctrl(btnM, 3, LV_BTNMATRIX_CTRL_RECOLOR);
    lv_obj_align(btnM, LV_ALIGN_CENTER, 0, 0);

 3.5 Check唯一性

通过lv_btnmatrix_set_one_checked将矩阵中的按钮具有Check唯一性。

lv_btnmatrix_set_btn_ctrl_all(btnM, 1 | LV_BTNMATRIX_CTRL_CHECKABLE);
lv_btnmatrix_set_one_checked(btnM, true);

 4. 事件

可以通过lv_btnmatrix_get_selected_btn获取事件对应的按钮ID,通过lv_btnmatrix_get_btn_text获取按钮的字符串。

在代码中添加事件回调函数

static void event_handler(lv_event_t* e)
{

}

lv_obj_add_event_cb(btnM, event_handler, LV_EVENT_ALL, NULL);

4.1 LV_EVENT_VALUE_CHANGED

static void 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);
    if (code == LV_EVENT_VALUE_CHANGED)
    {
        uint32_t id = lv_btnmatrix_get_selected_btn(obj);
        const char* txt = lv_btnmatrix_get_btn_text(obj, id);

        LV_LOG_USER("%s was pressed\n", txt);
    }
}

4.2 LV_EVENT_LONG_PRESSED

 增加Label显示信息。

static void 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);
    if (code == LV_EVENT_LONG_PRESSED)
    {
        uint32_t id = lv_btnmatrix_get_selected_btn(obj);
        lv_label_set_text_fmt(label1, "Long Pressed ID:%d", id);
    }
}

 

4.3 LV_EVENT_DRAW_PART_BEGIN

 这个事件常用于重绘,表示一个局部绘制的开始。

static void 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);
    if (code == LV_EVENT_DRAW_PART_BEGIN)
    {
        lv_obj_draw_part_dsc_t* dsc = lv_event_get_draw_part_dsc(e);
        if (dsc->class_p == &lv_btnmatrix_class && dsc->type == LV_BTNMATRIX_DRAW_PART_BTN)
        {
            if (dsc->id == 1)
            {
                if (lv_btnmatrix_get_selected_btn(obj) == dsc->id)
                    dsc->rect_dsc->bg_color = lv_palette_darken(LV_PALETTE_BLUE, 3);
                else
                    dsc->rect_dsc->bg_color = lv_palette_main(LV_PALETTE_BLUE);

            }
        }
    }
}

将第二个按钮的背景色改为蓝色。

还有一个LV_EVENT_DRAW_PART_END的事件,这个事件是刷新完按钮才响应的,可以用于在按钮上添加图片。

  • 5
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值