LVGL中实体按键的使用
在某些屏幕上我们没有触摸功能,则需要使用按键操作控件
lvgl总共给了我们四种设备输入接口,分别是
1、LV_INDEV_TYPE_POINTER 触摸板或鼠标
2、LV_INDEV_TYPE_KEYPAD 键盘或小键盘
3、LV_INDEV_TYPE_ENCODER 编码器,带有左/右转和推动选项
4、LV_INDEV_TYPE_BUTTON 外部按钮虚拟按下屏幕
我们使用实体按键适用第二种或第四种输入方式,但是第四种输入方式局限性较大,只能作为一个按下屏幕的虚拟的点,也就是说,我们如果有三个按键,只能模拟三个点在屏幕按下;所以我们使用LV_INDEV_TYPE_KEYPAD 作为输入方式。
LV_INDEV_TYPE_KEYPAD可以传递以下几种状态,如果可能我们可以连接一个真正的键盘来传递所有的值。
LV_KEY_NEXT 聚焦到下一个对象
LV_KEY_PREV 聚焦到上一个对象
LV_KEY_ENTER 触发 LV_EVENT_PRESSED/CLICKED/LONG_PRESSED 等事件
LV_KEY_UP 增加值或向上移动
LV_KEY_DOWN 减少值或向下移动
LV_KEY_RIGHT 增加值或向右移动
LV_KEY_LEFT 减少值或向左移动
LV_KEY_ESC 关闭或退出(例如关闭 下拉列表)
LV_KEY_DEL 删除(例如 文本区域 中右侧的字符)
LV_KEY_BACKSPACE 删除左边的一个字符(例如在文本区域)
LV_KEY_HOME 跳到开头/顶部(例如在 文本区域)
LV_KEY_END 跳到最后(例如在 文本区域))
如何在我们的工程中实现键盘功能:
1、硬件上必须要有三个按键,根据自己的连接方式进行初始化:
void key_init(void)
{
gpio_pad_select_gpio(KEY1);
gpio_pad_select_gpio(KEY2);
gpio_pad_select_gpio(KEY3);
gpio_pad_select_gpio(KEY4);
gpio_pad_pullup(KEY1);
gpio_pad_pullup(KEY2);
gpio_pad_pullup(KEY3);
gpio_pad_pullup(KEY4);
gpio_set_direction(KEY1, GPIO_MODE_INPUT);
gpio_set_direction(KEY2, GPIO_MODE_INPUT);
gpio_set_direction(KEY3, GPIO_MODE_INPUT);
gpio_set_direction(KEY4, GPIO_MODE_INPUT);
}
2、设定按键读取函数,返回值与上述键值相对应:
int read_key(void)
{
if(gpio_get_level(KEY1)==0)
{
return LV_KEY_PREV;
}
else if (gpio_get_level(KEY2)==0)
{
return LV_KEY_NEXT;
}
else if (gpio_get_level(KEY4)==0)
{
return LV_KEY_ENTER;
}
else
{
return -1;
}
}
3、在初始化函数中配置注册设备:
lv_indev_t *mydev=NULL; //这个与后续的group相绑定
lv_indev_drv_t indev_drv_key;
lv_indev_drv_init(&indev_drv_key);
indev_drv_key.read_cb = button_read;
indev_drv_key.type = LV_INDEV_TYPE_KEYPAD;
mydev=lv_indev_drv_register(&indev_drv_key);
4、设备回调函数:
void button_read(lv_indev_drv_t * drv, lv_indev_data_t*data){
static uint32_t last_btn = 0; /*Store the last pressed button*/
int btn_pr = read_key(); /*Get the ID (0,1,2...) of the pressed button*/
if(btn_pr >= 0) { /*Is there a button press? (E.g. -1 indicated no button was pressed)*/
last_btn = btn_pr; /*Save the ID of the pressed button*/
data->state = LV_INDEV_STATE_PRESSED; /*Set the pressed state*/
} else {
data->state = LV_INDEV_STATE_RELEASED; /*Set the released state*/
}
data->key = last_btn; /*Save the last button*/
}
5、新增了设备还要与group相绑定,不然无法起到作用,新建三个对象用来做演示:
extern lv_indev_t *mydev;
static void btn_event_handler(lv_event_t * e)//按键回调函数
{
lv_event_code_t code = lv_event_get_code(e);
if(code == LV_EVENT_CLICKED) {
LV_LOG_USER("Clicked");
}
else if(code == LV_EVENT_VALUE_CHANGED) {
LV_LOG_USER("Toggled");
}
}
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);
static int i = 0;
if(code == LV_EVENT_CLICKED){
printf("\r\nclick = %d",code);
if(i++ >12)
i=0;
lv_roller_set_selected(obj, i, LV_ANIM_ON);
}
}
void lv_example(void)
{
lv_obj_t *scr = lv_scr_act();
lv_group_t *group = lv_group_create();
lv_group_set_default(group);
lv_indev_set_group(mydev, group);
lv_group_focus_obj(group); //分组聚焦到对象
lv_group_set_editing(group, true); //编辑模式
lv_obj_t * label;
lv_obj_t * btn1 = lv_btn_create(lv_scr_act());
lv_obj_add_event_cb(btn1, btn_event_handler, LV_EVENT_ALL, NULL);
lv_obj_align(btn1, LV_ALIGN_CENTER, -50, -40);
label = lv_label_create(btn1);
lv_label_set_text(label, "Button");
lv_obj_center(label);
lv_obj_t * btn2 = lv_btn_create(lv_scr_act());
lv_obj_add_event_cb(btn2, btn_event_handler, LV_EVENT_ALL, NULL);
lv_obj_align(btn2, LV_ALIGN_CENTER, -50, 40);
lv_obj_add_flag(btn2, LV_OBJ_FLAG_CHECKABLE);
lv_obj_set_height(btn2, LV_SIZE_CONTENT);
label = lv_label_create(btn2);
lv_label_set_text(label, "Toggle");
lv_obj_center(label);
lv_obj_t *roller1 = lv_roller_create(scr);
lv_roller_set_options(roller1,
"January\n"
"February\n"
"March\n"
"April\n"
"May\n"
"June\n"
"July\n"
"August\n"
"September\n"
"October\n"
"November\n"
"December",
LV_ROLLER_MODE_INFINITE);
lv_roller_set_visible_row_count(roller1, 4);
lv_obj_set_pos(roller1,150,100);
lv_obj_add_event_cb(roller1, event_handler, LV_EVENT_ALL, NULL);
lv_group_add_obj(group ,btn1);
lv_group_add_obj(group ,btn2);
lv_group_add_obj(group ,roller1);
}
最终效果:
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。