| **银杏科技有限公司旗下技术文档发布平台** |||| |技术支持电话|**0379-69926675-801**||| |技术支持邮件|Gingko@vip.163.com||| ^ 版本 ^ 日期 ^ 作者 ^ 修改内容 ^ | V1.0 | 2021-01-03 | yang | 初次建立 | ===== 实验三十二:lv_btnmatrix矩阵按钮 ===== ==== 一、矩阵按钮 ==== 矩阵按钮控件可以在行和列中显示多个按钮,并且每个按钮都可以设置标签、相对大小和按钮的各种属性。矩阵按钮的主要部分称为 **LV_BTNMATRIX_PART_BG** ,它使用典型的背景样式属性绘制背景。**LV_BTNMATRIX_PART_BTN** 是虚拟部分,它指的是按钮矩阵上的按钮。背景中的 **top/bottom/left/right** 填充值用于在侧面保留一些空间,而设置按钮之间的距离应使用内部填充。 需要注意的是,矩阵按钮对象可以看作是一系列伪按钮的集合,它不是真正的 **lv_btn** 按钮对象,而是 **lv_btnmatrix** 内部纯绘制出来的具有按钮外观的图形,而且这个图形具有和 **lv_btn** 按钮一样的点击效果,这种伪按钮的好处是它基本不占内存消耗(一个伪按钮大概需要 **8** 个字节,而容器加普通按钮对象组合大概需要**100-150** 字节),这属于**LVGL** 的一种优化操作。所以如果你有多个按钮集合的应用场景的话,最好使用矩阵按钮控件,而不要去使用容器外加普通按钮的方案。 不过这种优化的缺点是,将各个按钮的样式设置为与其他按钮不同的功能受到限制(除了切换功能之外)。如果需要设置不同按钮使用不同的样式,则使用单个按钮很可能是一种更好的方法。 ==== 二、矩阵按钮的设置 ==== === 2.1、按钮文字 === 在矩阵按钮中的每个按钮上都有一个文本标签。要指定它们,需要使用一个称为 **map** 的描述符字符串数组,使用 **lv_btnmatrix_set_map(btnm, my_map)** 将传入描述符字符串数组。**map**的声明形式应为**const char * map[] = {"btn1", "btn2", "btn3", ""}** ,请注意,最后一个元素必须为空字符串!在描述符字符串数组中使用 "**\n**" 起换行作用,例如 **{"btn1", "btn2", "\n", "btn3", ""}**将创建下图所示的矩阵按钮。 {{ :icore4t:icore4t_rtt_lvgl_32_1.png?direct |}} === 2.2、控制按钮 === 矩阵按钮中按钮的宽度可以用 **lv_btnmatrix_set_btn_width(btnm, btn_id, width)** 来设置为相对于同一行其他按钮的宽度比例,例如一行中有两个按钮:btnA宽度= 1 和btnB 宽度= 2,btnA 将有 33%的行宽度而 btnB 将有 66%的行宽度。这类似于CSS中的flex-grow属性的工作方式。若按钮的宽度不进行单独设置,则每行按钮的宽度自动平分矩阵按钮的宽度。除了宽度,每个按钮都可以使用以下参数进行自定义: * **LV_BTNMATRIX_CTRL_HIDDEN** 将按钮隐藏(隐藏的按钮仍占据布局中的空间,它们不可见或不可单击)。 * **LV_BTNMATRIX_CTRL_NO_REPEAT** 长按按钮时禁用重复触发。 * **LV_BTNMATRIX_CTRL_DISABLED** 禁用按钮。 * **LV_BTNMATRIX_CTRL_CHECKABLE** 启用按钮的切换功能。 * **LV_BTNMATRIX_CTRL_CHECK_STATE** 设置当前为已切换的状态。 * **LV_BTNMATRIX_CTRL_CLICK_TRIG** 如果为 0,按钮将在按下时触发回调函数,如果为1,则在释放时触发。 设置或清除按钮的控件属性,分别使用 **lv_btnmatrix_set_btn_ctrl(btnm, btn_id, LV_BTNM_CTRL_...)** 和 **lv_btnmatrix_clear_btn_ctrl(btnm, btn_id, LV_BTNM_CTRL_...)**。为按钮矩阵的所有按钮设置/清除相同的控件属性,请使用 **lv_btnmatrix_set_btn_ctrl_all(btnm, btn_id, LV_BTNM_CTRL_...)** 和**lv_btnmatrix_clear_btn_ctrl_all(btnm, btn_id, LV_BTNM_CTRL_...)**。 使用**lv_btnmatrix_set_ctrl_map(btnm, ctrl_map)** 为按钮矩阵设置控制**map**(类似于文本的描述符字符串数组)。**ctrl_map**的元素应类似于 **ctrl_mapctrl_map[0] = width | LV_BTNM_CTRL_NO_REPEAT | LV_BTNM_CTRL_TGL_ENABLE**,其中元素的数量应等于按钮的数量(不包括换行符)。 === 2.3、一次检测 === 用户可以使用 **lv_btnmatrix_set_one_check(btnm, true)** 来启用“**one check**”功能,一次只允许检测(切换)一个按钮。 === 2.4、重新着色 === 按钮上的文本可以开启类似于标签对象的重新着色功能。要启用它,请使用**lv_btnmatrix_set_recolor(btnm, true)**。之后,带有**#FF0000 btn1#** 文字的按钮将变为红色。 === 2.5、对齐按钮文字 === 使用**lv_btnmatrix_set_align(roller, LV_LABEL_ALIGN_LEFT/CENTER/RIGHT)**可以让按钮上的文本对齐,按钮矩阵中的所有文本项都将符合设置的对齐方式。 ==== 三、事件 ==== 除了通用事件外,矩阵按钮还发送以下特殊事件: * **LV_EVENT_VALUE_CHANGED** 在按下/释放按钮时或在长按之后重复时发送。事件数据为按钮的** ID**。 以下键值由按钮处理: * **LV_KEY_DOWN / UP / LEFT / RIGHT** 在按钮之间导航以选择一个 * **LV_KEY_ENTER** 按下/释放所选按钮 {{ :icore4t:icore4t_rtt_lvgl_32_2.gif?direct |}} lv_obj_t * label; int red_color_flag = 0; void event_handler(lv_obj_t * obj, lv_event_t event) /* 回调函数 */ { if(event == LV_EVENT_VALUE_CHANGED) { const char * txt = lv_btnmatrix_get_active_btn_text(obj);/* 获取按下的按键文本 */ rt_kprintf("%s was pressed\n", txt); /* 串口打印 */ if(!strcmp(txt, "red"))red_color_flag = !red_color_flag; /* red按钮状态切换 */ if(red_color_flag == 1)lv_label_set_text_fmt(label, "#ff0000 %s was pressed#\n", txt); /* 更新标签内容 */ else lv_label_set_text_fmt(label, "#000000 %s was pressed#\n", txt); } } static const char * btnm_map[] = {"1", "2", "3", "4", "5", "\n", "6", "7", "8", "9", "0", "\n", "red", "Action2", ""}; /* 按键分布图 */ void lv_gui_run(void) { lvgl2rtt_init("lcd"); /* 初始化lvgl2rtt */ label = lv_label_create(lv_scr_act(), NULL); /* 创建标签 */ lv_obj_set_pos(label, 20, 20); /* 设置显示坐标 */ lv_label_set_recolor(label, true); /* 使能重新着色 */ lv_label_set_text(label, " NULL was pressed\n"); /* 设置初始内容 */ lv_obj_t * btnm1 = lv_btnmatrix_create(lv_scr_act(), NULL); /* 创建矩阵按钮 */ lv_obj_set_size(btnm1, 200, 100); /* 设置尺寸 */ lv_btnmatrix_set_map(btnm1, btnm_map); /* 传入按键分布图 */ lv_btnmatrix_set_btn_width(btnm1, 10, 2); /* 设置"red"的宽度为"Action2"的两倍 */ lv_btnmatrix_set_btn_ctrl(btnm1, 10, LV_BTNMATRIX_CTRL_CHECKABLE);/* 使能按钮切换 */ lv_btnmatrix_set_btn_ctrl(btnm1, 11, LV_BTNMATRIX_CTRL_CHECK_STATE); /* 设置按钮为已切换状态 */ lv_obj_align(btnm1, NULL, LV_ALIGN_CENTER, 0, 0); /* 设置位置 */ lv_obj_set_event_cb(btnm1, event_handler); /* 设置回调函数 */ }