shishu 发表于 2023-2-26 23:46:28

LVGL用纯物理按键做导航的问题

各位好!最近小弟在使用LVGL8.2做界面,CPU使用ESP32,硬件没有使用触摸屏只有上下左右和ok键几个按键作为输入。现在在codeblocks上做仿真模拟这个是主桌面的界面,

界面使用group和按键关联起来,最后能在键盘上按pageup和pagedown来一个个移动到要点击的图标上,按enter输入来确认进入。比如进入到wifi设定界面。

最后pageup和pagedow到要输入密码的wifi按enter进入到输入密码的界面。
最后来到输入密码的界面,界面上有一个lv_keboard.

使用了keyboard才知道,导航可以使用上下左右箭头来自由定位到要点击的按钮字符。而不仅仅是pageup和pagedown一个个移动输入,比如home界面移动到第二排就直接按下键就可以
移动到,不要pagedown一个个按四次到第二排。但是lv_keyboard到底是如何实现按钮的 LV_KEY_DOWN LV_KEY_RIGHT LV_KEY_LEFT等按键的监听的。也就是说keboard这个控件
只要按键上下左右有动作就监听到最后移动了里面选择的按钮。我用了很多方法都没有实现。起初以为lvgl只能使用group方式pageup和pagedown来移动。最后说一句界面的布局是
使用的squareline studio v1.2来图形化拖拽的方式实现的。用的30天试用版本。各位大神有遇到过类似的案例吗?
谢谢大家了

Huaan 发表于 2023-2-27 13:47:23

本帖最后由 Huaan 于 2023-2-27 13:49 编辑

试试lv_group_set_editing,切换编辑模式和导航模式

chen849928055 发表于 2023-2-27 14:19:49

楼主用ESP32-S3做的

shishu 发表于 2023-2-27 16:59:22

Huaan 发表于 2023-2-27 13:47
试试lv_group_set_editing,切换编辑模式和导航模式
(引用自2楼)

好的谢谢了我待会试试

cnxh 发表于 2023-2-27 17:58:25

数据和程序存spi,flash中,刷新速度够吗

zhangling520 发表于 2023-2-27 19:09:41

好像要用网格布局才能用箭头按键 导航

shishu 发表于 2023-2-27 19:42:17

zhangling520 发表于 2023-2-27 19:09
好像要用网格布局才能用箭头按键 导航
(引用自6楼)

squareline中没有这个容器组件,只能使用Panel(就是基础的lv_obj_t*)类型来容纳其他的图标什么的,因为它是基础类型 没有提供左右按键导航的功能。其他组件像lv_table_t*作为容器可以提供导航。但是它又太简单了,只能在里面容纳文本的label控件等,不能自定义放控件。而且不在squareline中提供拖拽支持,只能自己写代码。还是一些studio ide提供的图形化编程功能太弱了。

shishu 发表于 2023-2-27 19:43:04

cnxh 发表于 2023-2-27 17:58
数据和程序存spi,flash中,刷新速度够吗
(引用自5楼)

现在还是模拟仿真其他没试

shishu 发表于 2023-2-28 00:43:36

本帖最后由 shishu 于 2023-2-28 00:54 编辑

各位暂时算临时解决了这个问题。
经过实验发现squareline的拖拽容器只有panel,可以在panel上面放图片和按钮。可以自己自定义组合各种控件,但是遗憾的panel控件就是基础控件lv_obj_t,它没有复杂的layout布局控制,内部默认的构建函数和回调函数里面没有对上下左右导航的处理,最后导致panel父容器不能通过方向键来导航到子控件上。但是如果把父控件里面的子控件一个个绑定到group,group和按键关联后可以通过pageup、down来导航放入到group里面的子控件。后来查看gourp和indev的源代码。发现group的代码里面实际上有左右上下导航的处理。但是条件比较苛刻,比如两个父控件panel添加到group,一个父控件设定为focus状态,这个时候通过方向键可以导航这个父控件下的子控件一次,但是导航到这个子控件后,父控件失去focus就无法导航第二个子控件,这里的一个过滤的地方就是group的父控件要获得焦点才能导航其下面的子控件,矛盾的地方就是子控件因为导航获得焦点后父控件失去焦点无法再导航。这里我修改了源码,源码只适用我自己的情况。就是往group里面只放置一个父控件。home界面的8个小图标都是在一个大的panel父控件里面,然后修改源码在group里面只有一个父控件的时候不论父控件有没有获得焦点直接传递event到后面。代码如下:
原代码:
lv_res_t lv_group_send_data(lv_group_t * group, uint32_t c)
{
    lv_obj_t * act = NULL;
   act = lv_group_get_focused(group);
    if(act == NULL) return LV_RES_OK;

    if(lv_obj_has_state(act, LV_STATE_DISABLED)) return LV_RES_OK;

    return lv_event_send(act, LV_EVENT_KEY, &c);
}
被修改为:
lv_res_t lv_group_send_data(lv_group_t * group, uint32_t c)
{
    lv_obj_t * act = NULL;
    if(lv_group_get_obj_count(group)==1){
      lv_obj_t ** obj_i;
      obj_i = _lv_ll_get_head(&group->obj_ll);
      if(*obj_i!=NULL)
            act = *obj_i;
    }else{
      act = lv_group_get_focused(group);
    }

    if(act == NULL) return LV_RES_OK;

    if(lv_obj_has_state(act, LV_STATE_DISABLED)) return LV_RES_OK;

    return lv_event_send(act, LV_EVENT_KEY, &c);
}
这样最后一句lv_event_send(act, LV_EVENT_KEY, &c);都会执行,会把keycode传递给父控件上。
父控件设置回调函数。监控上下左右和enter的输入,自己在回调函数中手动的调整选择的子控件。
lv_group_send_data函数在lv_group.c   lvgl版本是8.2
页: [1]
查看完整版本: LVGL用纯物理按键做导航的问题