有8个按键要怎么实现UI
离线
lv_indev_t 和lv_indev_drv_t。
在 lv_indev_drv_t 的实例的回调函数(这个自定义)中:void evdev_btn_read(lv_indev_drv_t * drv, lv_indev_data_t * data),
给data->key赋值,LVGL预定义了很多按键比如LV_KEY_UP……,
然后设置data->state的状态: LV_INDEV_STATE_PR : LV_INDEV_STATE_REL就可以了,
8个按键已经是很丰富了。4个方向加确认取消,还有2个可以做其他用途。
离线
@regbbs
这个有找到,当不知到怎么更UI连接起来
switch(act_key) {
case 1:
act_key = LV_KEY_RIGHT;
break;
case 2:
act_key = LV_KEY_LEFT;
break;
case 3:
act_key = LV_KEY_UP;
break;
case 4:
act_key = LV_KEY_DOWN;
break;
case 5:
act_key = LV_KEY_ENTER;
break;
case 6:
act_key = LV_KEY_ESC;
break;
}
last_key = act_key;
离线
@huaze
static lv_group_t* group;
lv_indev_t* indev_keypad;
static lv_indev_drv_t kb_drv;
lv_indev_drv_init(&kb_drv);
kb_drv.type = LV_INDEV_TYPE_KEYPAD;
kb_drv.read_cb = 回调函数;
indev_keypad = lv_indev_drv_register(&kb_drv);
lv_indev_set_group(indev_keypad, group);
用这个来注册,然后把需要接收按键的控件加入group。
这样当有按键按下,LVGL会根据键值处理对应的按键。
回调函数(linux下的):
void evdev_btn_read(lv_indev_drv_t * drv, lv_indev_data_t * data)
{
struct input_event in;
while(read(evdev_fd, &in, sizeof(struct input_event)) > 0)
{
if(drv->type == LV_INDEV_TYPE_KEYPAD)
{
//4 button
switch(in.code&0xFF)
{
case 0x10:
data->key = LV_KEY_UP;
break;
case 0x11:
data->key = LV_KEY_DOWN;
break;
case 0x12:
data->key = LV_KEY_ENTER;
break;
case 0x13:
data->key = LV_KEY_ESC;
break;
default:
data->key = 0;
break;
}
if (data->key != 0)
{
/* Only record button state when actual output is produced to prevent widgets from refreshing */
data->state = (in.value) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
}
evdev_key_val = data->key;
evdev_button = data->state;
if(data->state == LV_INDEV_STATE_PR)
{
keyPushed = true;
}
return;
}
}
}
如果是单片机平台,
read(evdev_fd, &in, sizeof(struct input_event)这里来通过读取GPIO来获取按键状态
离线
@regbbs
回调函数有,但是控件只有部分按键有实际效果
static void keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{
static uint32_t last_key = 0;
/*Get whether the a key is pressed and save the pressed key*/
uint32_t act_key = keypad_get_key();
if(act_key != 0) {
data->state = LV_INDEV_STATE_PR;
LOG_D("act_key = %d",act_key);
//beep(1, 100, 50, 0);
/*Translate the keys to LVGL control characters according to your key definitions*/
switch(act_key) {
case 1:
act_key = LV_KEY_LEFT;//左
break;
case 2:
act_key = LV_KEY_PREV;//上
break;
case 3:
act_key = LV_KEY_RIGHT;//右
break;
case 4:
act_key = LV_KEY_NEXT;//下
break;
case 5:
act_key = LV_KEY_HOME;//返回
break;
case 6:
act_key = LV_KEY_ENTER;//确定
break;
}
last_key = act_key;
}
else {
data->state = LV_INDEV_STATE_REL;
}
data->key = last_key;
}
离线
这些按钮相关控件要添加到按键group里去。
离线
@huaze
是这样的,控件只处理一部分按键消息,所以得自己再处理一部分。给控件添加回调函数即可。
而有些控件不接受按键消息的,需要看看控件支持的事件中按键部分,然后看控件是否合适,或者是用控件组合来实现需要的功能。
最近编辑记录 regbbs (2023-12-16 11:33:05)
离线
@regbbs
不理解要怎么做,可能是刚接触LVGL
离线
@regbbs
修改回调,是这意思吗
void ui_event_Button( lv_event_t * e)
{
lv_event_code_t event_code = lv_event_get_code(e);
lv_obj_t * target = lv_event_get_target(e);
if (button_fun() == 0) return;//防抖
LOG_I("get_key :%d", lv_event_get_key(e));
if ( event_code == LV_EVENT_KEY && lv_event_get_key(e) == LV_KEY_RIGHT )
{
lv_group_focus_next(groupRect);
}
}
void test2()
{
lv_obj_t * button = lv_btn_create(lv_scr_act());
lv_obj_set_size(button, 80, 80);
lv_obj_set_pos(button, 100, 0);
lv_obj_add_event_cb(button, ui_event_Button, LV_EVENT_ALL, NULL);//UP
lv_obj_t * button1 = lv_btn_create(lv_scr_act());
lv_obj_set_size(button1, 80, 80);
lv_obj_set_pos(button1, 0, 100);
lv_obj_add_event_cb(button1, ui_event_Button, LV_EVENT_ALL, NULL);//UP
lv_obj_t * button2 = lv_btn_create(lv_scr_act());
lv_obj_set_size(button2, 80, 80);
lv_obj_set_pos(button2, 100, 100);
lv_obj_add_event_cb(button2, ui_event_Button, LV_EVENT_ALL, NULL);//UP
//注册组
groupRect = lv_group_create();
//绑定组
lv_group_add_obj(groupRect, button);
lv_group_add_obj(groupRect, button1);
lv_group_add_obj(groupRect, button2);
lv_indev_set_group(indev_keypad, groupRect);//设置默认组
}
离线
@huaze
是的,不过防抖放在回调函数或其他地方比较好
离线
@huaze
是的,不过防抖放在回调函数或其他地方比较好
非常感谢
离线
那这种界面,有没有控件直接使用
离线
lv_table
这个的例子在lvgl的例子有。https://docs.lvgl.io/master/widgets/table.html
需要自己处理绘制的回调函数和按键,有时候如果一个控件不接受焦点(不能处理按键等),可以用另一个代替,
然后在另一个的函数中控制不接受焦点的控件。
离线
@regbbs
能不能整个例子,倒腾了几天还是不行
物理按键控制不了滑动
DataStream_table_1 = lv_table_create(NULL);
lv_obj_set_pos(DataStream_table_1, 0, 0);
lv_obj_set_size(DataStream_table_1, 480, 220);
lv_table_set_col_width(DataStream_table_1, 0, 340);
lv_table_set_col_width(DataStream_table_1, 1, 130);
lv_table_set_cell_value(DataStream_table_1,0,0,"Name");
lv_table_set_cell_value(DataStream_table_1,1,0,"ENGING");
lv_table_set_cell_value(DataStream_table_1,2,0,"Banana");
lv_table_set_cell_value(DataStream_table_1,3,0,"Citron");
lv_table_set_cell_value(DataStream_table_1,4,0,"Name1");
lv_table_set_cell_value(DataStream_table_1,5,0,"Name2");
lv_table_set_cell_value(DataStream_table_1,6,0,"Name3");
lv_table_set_cell_value(DataStream_table_1,7,0,"Name4");
lv_table_set_cell_value(DataStream_table_1,8,0,"Name5");
lv_table_set_cell_value(DataStream_table_1,9,0,"Name6");
lv_table_set_cell_value(DataStream_table_1,0,1,"Value");
lv_table_set_cell_value(DataStream_table_1,1,1,"68.5 km/h");
lv_table_set_cell_value(DataStream_table_1,3,1,"$3");
lv_table_set_cell_value(DataStream_table_1,4,1,"Price1");
lv_table_set_cell_value(DataStream_table_1,5,1,"Price2");
lv_table_set_cell_value(DataStream_table_1,6,1,"Price3");
lv_table_set_cell_value(DataStream_table_1,7,1,"Price4");
lv_table_set_cell_value(DataStream_table_1,8,1,"Price5");
lv_table_set_cell_value(DataStream_table_1,9,1,"Price6");
lv_obj_add_event_cb(DataStream_table_1, DataStream_table_1_event_handler, LV_EVENT_KEY, NULL);
lv_group_add_obj(groupRect_Diag, DataStream_table_1);//绑定组
离线
可以自己定义按键处理函数,就是麻烦一点
离线
可以自己定义按键处理函数,就是麻烦一点
可以给个实例吗
离线
ktouch 说:可以自己定义按键处理函数,就是麻烦一点
可以给个实例吗
他这个表格不好用我就没用,你参考下自带的examples的widgets里面表格的绘制,用lv_table_add_cell_ctrl和lv_table_clear_cell_ctrl来
模拟被选中的行的效果,哪一行被选中倒是有函数lv_table_get_selected_cell来处理,不用外部变量来记录。
表格本身不接受按键消息,可以在窗口的按键消息种来处理表格的显示状态。
离线