您尚未登录。

楼主 # 2023-12-14 20:39:55

huaze
会员
注册时间: 2023-11-27
已发帖子: 24
积分: 19

LVGL 只有物理按键

有8个按键要怎么实现UI

离线

#1 2023-12-14 21:52:49

regbbs
会员
注册时间: 2020-04-06
已发帖子: 82
积分: 69.5

Re: LVGL 只有物理按键

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个可以做其他用途。

离线

楼主 #2 2023-12-15 11:47:40

huaze
会员
注册时间: 2023-11-27
已发帖子: 24
积分: 19

Re: LVGL 只有物理按键

@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;

离线

#3 2023-12-15 19:57:12

regbbs
会员
注册时间: 2020-04-06
已发帖子: 82
积分: 69.5

Re: LVGL 只有物理按键

@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来获取按键状态

离线

#4 2023-12-15 20:00:09

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 583
积分: 587
个人网站

Re: LVGL 只有物理按键

按键产生事件,GUI负责帮你分发事件,你逻辑代码,让事件和控件联系起来就行了。

离线

楼主 #5 2023-12-16 10:49:22

huaze
会员
注册时间: 2023-11-27
已发帖子: 24
积分: 19

Re: LVGL 只有物理按键

@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;
}

离线

#6 2023-12-16 10:57:26

EddyZhan
会员
注册时间: 2018-05-11
已发帖子: 59
积分: 153.5

Re: LVGL 只有物理按键

这些按钮相关控件要添加到按键group里去。

离线

#7 2023-12-16 11:31:02

regbbs
会员
注册时间: 2020-04-06
已发帖子: 82
积分: 69.5

Re: LVGL 只有物理按键

@huaze
是这样的,控件只处理一部分按键消息,所以得自己再处理一部分。给控件添加回调函数即可。
而有些控件不接受按键消息的,需要看看控件支持的事件中按键部分,然后看控件是否合适,或者是用控件组合来实现需要的功能。

最近编辑记录 regbbs (2023-12-16 11:33:05)

离线

楼主 #8 2023-12-16 15:32:58

huaze
会员
注册时间: 2023-11-27
已发帖子: 24
积分: 19

Re: LVGL 只有物理按键

@regbbs
不理解要怎么做,可能是刚接触LVGL

离线

楼主 #9 2023-12-16 16:24:22

huaze
会员
注册时间: 2023-11-27
已发帖子: 24
积分: 19

Re: 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);//设置默认组

}

离线

#10 2023-12-16 22:41:06

regbbs
会员
注册时间: 2020-04-06
已发帖子: 82
积分: 69.5

Re: LVGL 只有物理按键

@huaze
是的,不过防抖放在回调函数或其他地方比较好

离线

#11 2023-12-17 11:32:46

海石生风
会员
所在地: 深圳
注册时间: 2019-07-02
已发帖子: 660
积分: 793
个人网站

Re: LVGL 只有物理按键

regbbs 说:

@huaze
是的,不过防抖放在回调函数或其他地方比较好

用硬件去抖吧,关联一个104电容就行了,增加不了多少成本。
软件去抖,如果是裸机容易影响显示帧率。

离线

楼主 #12 2023-12-17 13:17:37

huaze
会员
注册时间: 2023-11-27
已发帖子: 24
积分: 19

Re: LVGL 只有物理按键

regbbs 说:

@huaze
是的,不过防抖放在回调函数或其他地方比较好

非常感谢

离线

楼主 #13 2023-12-17 15:38:16

huaze
会员
注册时间: 2023-11-27
已发帖子: 24
积分: 19

Re: LVGL 只有物理按键

QQ图片20231217131034.png
那这种界面,有没有控件直接使用

离线

#14 2023-12-18 08:53:25

regbbs
会员
注册时间: 2020-04-06
已发帖子: 82
积分: 69.5

Re: LVGL 只有物理按键

huaze 说:

https://whycan.com/files/members/13428/QQ图片20231217131034.png
那这种界面,有没有控件直接使用

lv_table
这个的例子在lvgl的例子有。https://docs.lvgl.io/master/widgets/table.html

需要自己处理绘制的回调函数和按键,有时候如果一个控件不接受焦点(不能处理按键等),可以用另一个代替,
然后在另一个的函数中控制不接受焦点的控件。

离线

楼主 #15 2024-01-17 10:55:40

huaze
会员
注册时间: 2023-11-27
已发帖子: 24
积分: 19

Re: LVGL 只有物理按键

@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);//绑定组

52539626-7096-4da4-B6F1-134C18102B8E.png

离线

#16 2024-01-17 19:15:05

ktouch
会员
注册时间: 2023-11-27
已发帖子: 18
积分: 3

Re: LVGL 只有物理按键

可以自己定义按键处理函数,就是麻烦一点

离线

楼主 #17 2024-01-18 09:46:37

huaze
会员
注册时间: 2023-11-27
已发帖子: 24
积分: 19

Re: LVGL 只有物理按键

ktouch 说:

可以自己定义按键处理函数,就是麻烦一点

可以给个实例吗

离线

#18 2024-01-18 16:45:25

regbbs
会员
注册时间: 2020-04-06
已发帖子: 82
积分: 69.5

Re: LVGL 只有物理按键

huaze 说:
ktouch 说:

可以自己定义按键处理函数,就是麻烦一点

可以给个实例吗

他这个表格不好用我就没用,你参考下自带的examples的widgets里面表格的绘制,用lv_table_add_cell_ctrl和lv_table_clear_cell_ctrl来
模拟被选中的行的效果,哪一行被选中倒是有函数lv_table_get_selected_cell来处理,不用外部变量来记录。

表格本身不接受按键消息,可以在窗口的按键消息种来处理表格的显示状态。

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn