目录
目的
实现一个如虚拟键盘似的按键阵列矩阵。以方便应用在计算器,键盘输入等场合。
功能描述
矩阵按键阵列实际和普通的button一样。只不过将多个button放在一起显示。稍微差异的是,此阵列是一个大对象,用户在创建和使用时,可以看作一个对象,组状的操作和配置。同时用户可以将此阵列看作一个数组,用户可以通过索引号获取阵列中的各个按键,查询各个按键的状态和属性、风格。
原理和功能函数描述
对于一个键盘而言,用户实现的过程是需要创建此键盘阵列,然后修改键盘的各个按钮的风格,如具体某个按键宽度,是否为开关功能(详细见button一章),是否单次按下事件中只有一个按钮有效等。然后配置其事件回调函数,实现事件响应的各个对应功能。
创建按钮矩阵
一个按钮矩阵创建很简单,和其他的模块对象一样,仅仅一个函数既能实现。
lv_obj_t *lv_btnm_create(lv_obj_t *par, constlv_obj_t *copy)
par:其父类(父窗口);
copy:参考的对象,用于初始化拷贝复制,一般NULL表示默认;
装饰和属性配置
按钮阵列被创建后,需要对阵列做些修饰。阵列的每个button需要配置对应的text,同时各个button的大小宽度可以做适当的调整。
-
按键的text配置
void lv_btnm_set_map(constlv_obj_t *btnm, const char *map[])
btnm:按键阵列
map:要配置阵列的text数组的首地址
const char **lv_btnm_get_map_array(constlv_obj_t *btnm)//获取map
用户可以采用const char * map[] = {"btn1", "btn2", "btn3", ""}的方式给要创建的队列一一配置text,如果需要多行的阵列,则可以采用"\n"来换行,如
{"btn1", "btn2", "\n", "btn3", ""},则会产生两行,首行为btn1和btn2,第二行为btn3.
-
按键的宽度配置
void lv_btnm_set_btn_width(constlv_obj_t *btnm, uint16_t btn_id, uint8_t width)
btnm:按键阵列
id:阵列中要被操作按钮的索引号;
width:配置其宽度
-
按键的开关属性配置
void lv_btnm_set_one_toggle(lv_obj_t *btnm, bool one_toggle)
btnm:被操作的阵列;
one_toggle:true,开启,false关闭
-
按键的属性配置
按键的宽度、开关属性、是否隐藏、是否有多击功能、是否有效、是否取相反的操作(即按钮高亮时为释放,按钮norml时为正常)。其属性如下:
LV_BTNM_CTRL_HIDDEN make a button hidden
LV_BTNM_CTRL_NO_REPEAT disable repeating when the button is long pressed
LV_BTNM_CTRL_INACTIVE make a button inactive
LV_BTNM_CTRL_TGL_ENABLE enable toggling of a button
LV_BTNM_CTRL_TGL_STATE set the toggle state
LV_BTNM_CTRL_CLICK_TRIG if 0 the button will react on press, if 1 will react on release
- 用户可以采用和text一样的方式,采用一个数组,每个数组配置一组属性,配置对应index的按钮属性。如ctrl_map[0] = width | LV_BTNM_CTRL_NO_REPEAT | LV_BTNM_CTRL_TGL_ENABLE配置的是按钮0的宽度、不可重击,开关属性。
具体函数如下:
void lv_btnm_set_ctrl_map(constlv_obj_t *btnm, constlv_btnm_ctrl_t ctrl_map[])//设置各个按键的属性
void lv_btnm_set_btn_ctrl(constlv_obj_t *btnm, uint16_t btn_id, lv_btnm_ctrl_t ctrl)//设置对应ID索引按钮的属性
void lv_btnm_clear_btn_ctrl(constlv_obj_t *btnm, uint16_t btn_id, lv_btnm_ctrl_t ctrl)
void lv_btnm_set_btn_ctrl_all(lv_obj_t *btnm, lv_btnm_ctrl_t ctrl)//所有按钮属性一样
void lv_btnm_clear_btn_ctrl_all(lv_obj_t *btnm, lv_btnm_ctrl_t ctrl)
bool lv_btnm_get_btn_ctrl(lv_obj_t *btnm, uint16_t btn_id, lv_btnm_ctrl_t ctrl)//获取id的属性是否使能,true,disabled,false:enable
-
按键的风格
void lv_btnm_set_style
(lv_obj_t *btnm, lv_btnm_style_t type, const lv_style_t *style)
const lv_style_t *lv_btnm_get_style
(constlv_obj_t *btnm, lv_btnm_style_ttype)
-
其他
void lv_btnm_set_pressed(constlv_obj_t *btnm, uint16_t id)//id按键为按下状态
uint16_t lv_btnm_get_pressed_btn(constlv_obj_t *btnm)//获取按下的按键id
const char *lv_btnm_get_btn_text(constlv_obj_t *btnm, uint16_t btn_id)//获取id的text
const char *lv_btnm_get_active_btn_text(constlv_obj_t *btnm)//最后一次操作的id的text
uint16_t lv_btnm_get_active_btn(constlv_obj_t *btnm)//最新一次被操作的按键id;
事件
当按下时,会产生一个LV_EVENT_VALUE_CHANGED的事件信号,具体操作通button按钮。
案列代码
#include "ljy_buttonm.h"
#include "lvgl/lvgl.h"
#include <stdio.h>
static void ButtonMCb(lv_obj_t * obj, lv_event_t event)
{
if(event == LV_EVENT_VALUE_CHANGED) {//按键发生动作
const char * txt = lv_btnm_get_active_btn_text(obj);//获取最后一次动作的按键文本
printf("%s was pressed\n", txt);
}
}
static const char * btnm_map[] = {"1", "2", "3", "4", "5", "\n",
"6", "7", "8", "9", "0", "\n",
"Action1", "Action2", ""};
void DrawButtonM(void)
{
lv_obj_t * btnm1 = lv_btnm_create(lv_scr_act(), NULL);//创建按键阵列
lv_btnm_set_map(btnm1, btnm_map);//配置text
lv_btnm_set_btn_width(btnm1, 10, 2); //配置按钮第bitnm_[10]对应的action1的宽度为2倍的action2
lv_obj_align(btnm1, NULL, LV_ALIGN_CENTER, 0, 0);//配置为中心对称
lv_obj_set_event_cb(btnm1, ButtonMCb);//配置事件
结果
当按下时,打印对应按键text。