LVGL 无触摸屏控件导航:Keypad and Encoder 演示工程源码解析与移植参考
嵌入式物联网智能硬件嵌入式GUI硬件开发【免费下载链接】HoloCubic带网络功能的伪全息透明显示桌面站项目地址https://gitcode.com/gh_mirrors/ho/HoloCubic点击查看免费下载导读LVGL本仓库内为 v7.6.1并不强制要求触摸屏才能操作界面——通过键盘Keypad或旋转编码器Encoder这两类输入设备同样可以完成按钮、下拉框、滚轮、滑条、开关、文本框等全部常用控件的选择、进入与编辑。本文以仓库中 lv_demo_keypad_encoder 演示的 README 为主体结合其 源码实现完整讲解该演示的功能范围、启用步骤、分组导航机制、编辑模式与虚拟键盘工作流并给出在 HoloCubic 这类带编码器硬件的嵌入式项目中的落地参考。读完本文你将掌握“如何让一个不含触摸屏的 LVGL 界面支持完整导航与文本输入”的整套方案。Demo 概览无触摸屏的控件导航原文档开篇即点明了该演示的核心价值LVGL 允许在不使用触摸板touchpad的情况下通过键盘和/或编码器来控制控件。演示的目的就是展示在没有触摸屏时如何操作以下控件类型按钮Button复选框Checkbox滑条Slider开关Switch数字微调框Spinbox下拉列表Drop-down list滚轮选择器Roller列表List文本框/文本输入Text area / text input上图即仓库中该演示的运行界面截图800×480画面由两个 Tab 页组成左侧 Selectors 页集中展示了上述各类选择型控件右侧 Text input 页则演示无触摸屏下的文本输入。如何运行该演示原文档给出了两步运行指引下面结合仓库实际配置展开为完整的启用流程。第一步在lv_ex_conf.h中开启演示宏找到 lv_ex_conf.h将演示开关从 0 改为 1/*Demonstrate the usage of encoder and keyboard*/ #define LV_USE_DEMO_KEYPAD_AND_ENCODER 1需要说明的是仓库中默认值为 0在 lv_ex_conf_template.h 中同样默认为 0即该演示在 HoloCubic 固件中默认未启用如需验证可临时打开再编译。同时需要注意两个可选辅助开关它们决定了演示是否会注册对应的模拟输入设备宏默认值作用LV_EX_KEYBOARD0为部分示例添加 PC 键盘支持需要lv_drivers仓库即模拟器中的键盘驱动LV_EX_MOUSEWHEEL0为部分示例添加“编码器”鼠标滚轮模拟支持同样依赖lv_drivers这两个宏在 lv_ex_conf.h 中定义。开启后演示代码会在初始化时通过lv_drivers提供的keyboard_read/mousewheel_read注册 Keypad 与 Encoder 类型的输入设备见下文源码解析。第二步在初始化完成后调用演示入口在lv_init()与各驱动初始化完成之后调用lv_demo_keypad_encoder();该函数声明位于 lv_demo_keypad_encoder.h整个示例被#if LV_USE_DEMO_KEYPAD_AND_ENCODER包裹宏未开启时函数体不参与编译。需要注意的是演示内部会调用lv_tabview_create等在“当前活动屏幕”上建控件因此调用前必须确保显示驱动已经初始化且存在默认显示。源码结构剖析演示是怎么搭起来的演示由三个文件组成位于 lv_demo_keypad_encoder 目录README.md—— 本文主体所依据的说明文档lv_demo_keypad_encoder.h—— 对外仅暴露lv_demo_keypad_encoder()入口lv_demo_keypad_encoder.c—— 全部界面与交互逻辑约 300 行。初始化流程入口函数lv_demo_keypad_encoder()lv_demo_keypad_encoder.c按顺序完成五件事创建输入分组并设置焦点回调g lv_group_create(); lv_group_set_focus_cb(g, focus_cb);分组lv_group_t是 LVGL 无触摸导航的核心对象后面会专门讲解。条件注册键盘输入设备当LV_EX_KEYBOARD开启时lv_indev_drv_t kb_drv; lv_indev_drv_init(kb_drv); kb_drv.type LV_INDEV_TYPE_KEYPAD; kb_drv.read_cb keyboard_read; lv_indev_t * kb_indev lv_indev_drv_register(kb_drv); lv_indev_set_group(kb_indev, g);条件注册编码器输入设备当LV_EX_MOUSEWHEEL开启时用鼠标滚轮模拟lv_indev_drv_t enc_drv; lv_indev_drv_init(enc_drv); enc_drv.type LV_INDEV_TYPE_ENCODER; enc_drv.read_cb mousewheel_read; lv_indev_t * enc_indev lv_indev_drv_register(enc_drv); lv_indev_set_group(enc_indev, g);创建 Tabview 与两个 Tab 页t1 Selectors、t2 Text input并把tv加入分组g。填充各页内容调用selectors_create(t1)、text_input_create(t2)最后弹出启动消息框msgbox_create()。Selectors 页八大选择型控件selectors_create() 在页面上按“列居中”布局依次创建lv_btn_create—— 按钮标签为 Buttonlv_checkbox_create—— 复选框lv_slider_create—— 滑条范围 0~10lv_switch_create—— 开关lv_spinbox_create—— 数字微调框lv_dropdown_create—— 下拉列表并注册了dd_enc事件回调对LV_EVENT_VALUE_CHANGED做出响应lv_roller_create—— 滚轮选择器lv_list_create—— 列表高度超过页面时自动收缩并添加了 Apply / Close / Show / Hide / Delete / Copy / Paste 七个带LV_SYMBOL_*图标的按钮项。这八类控件正好覆盖了 LVGL 中“可编辑editable”与“不可编辑”两类交互形态是验证分组导航能力最齐全的集合。Text input 页无触摸屏的文本输入text_input_create() 创建两个单行文本框ta1、ta2后者继承前者样式初始隐藏光标并设置占位文本 Type something。真正有趣的是ta_event_cb当文本框获得焦点且分组处于编辑模式时会动态创建一个虚拟键盘lv_keyboard_create把键盘与文本框绑定并将焦点移交到键盘——这就是“无触摸屏输入文字”的完整闭环详见后文事件回调一节。启动消息框msgbox_create() 在顶层图层弹出欢迎消息框 Welcome to the keyboard and encoder demo含 Ok / Cancel 两个按钮并将消息框加入分组后直接聚焦它lv_group_focus_obj(mbox)。如果启用了滚轮模拟还会预先lv_group_set_editing(g, true)让分组进入编辑状态。顶层图层被设置为半透明灰色且可点击用于在消息框显示期间屏蔽背景操作。关键机制一输入设备类型与数据约定演示注册的两种设备类型定义在 lv_hal_indev.hLV_INDEV_TYPE_KEYPAD, /** Keypad or keyboard*/ LV_INDEV_TYPE_ENCODER, /** Encoder with only Left, Right turn and a Button*/两者的读取数据约定也由同一个头文件定义Keypad 设备通过data-key上报当前按键lv_hal_indev.hEncoder 设备通过data-enc_diff上报“自上次读取以来的步数”通过data-state上报LV_INDEV_STATE_PR/LV_INDEV_STATE_RELlv_hal_indev.h。在底层 lv_indev.c 的indev_encoder_proc()中可以看到编码器按下LV_INDEV_STATE_PR且键值为LV_KEY_ENTER时触发“确认/进入”LV_KEY_LEFT/LV_KEY_RIGHT被转换为enc_diff的增减从而模拟编码器左右旋转长按LV_KEY_ENTER则会切换分组的编辑模式对可编辑控件生效。这说明编码器本质上被抽象成了“左/右转 一个按钮”与触摸无关。关键机制二分组Group导航与编辑模式无触摸导航的全部秘密都藏在lv_group中。演示在 lv_group.c 的基础上使用了以下 APIAPI行号作用lv_group_create()/lv_group_add_obj(g, obj)L110创建分组并把控件加入分组同一对象不可重复加入lv_group_set_focus_cb(g, cb)L310设置焦点变化回调用于滚动页面让焦点控件可见lv_group_focus_obj(obj)L212将焦点移动到指定对象会先解除当前焦点并发出LV_EVENT_DEFOCUSEDlv_group_set_editing(g, edit)L320切换/退出编辑模式演示里的focus_cblv_demo_keypad_encoder.c是理解“焦点如何在页面内滚动”的样板每当焦点对象改变它读取当前 Tab 页编号调用lv_page_focus(t1/t2, obj, LV_ANIM_ON)把对应页面滚动到焦点控件位置从而保证焦点永远可见。而tv_event_cblv_demo_keypad_encoder.c处理 Tab 切换当 Tab 页改变或收到LV_EVENT_REFRESH时先清空分组lv_group_remove_all_objs(g)再依据当前 Tab 把该页的控件结构体数组selector_objs或textinput_objs整体重新加入分组。这是“不同页共享一个分组、焦点随页重建”的经典写法。关键机制三虚拟键盘与事件驱动流程ta_event_cblv_demo_keypad_encoder.c完整展示了文本框在无触摸屏下的输入流程文本框获得焦点LV_EVENT_FOCUSED时显示光标若分组处于编辑模式则创建虚拟键盘控件lv_keyboard_create加入分组并绑定当前文本框lv_keyboard_set_textarea(kb, ta)把焦点交给键盘并通过lv_page_focus让页面滚动到文本标签处文本框失焦LV_EVENT_DEFOCUSED时隐藏光标。kb_event_cblv_demo_keypad_encoder.c则负责收尾先调用lv_keyboard_def_event_cb(kb, e)走默认键盘逻辑当收到LV_EVENT_APPLY确认或LV_EVENT_CANCEL取消时把焦点交还给文本框、删除虚拟键盘并把 Tabview 高度恢复为整屏。模拟器验证鼠标滚轮模拟编码器在没有真实编码器硬件时仓库自带的 Windows 模拟器工程 LvglSimulator 提供了现成的验证途径——lv_drivers/indev中的 mousewheel.c 把鼠标滚轮映射为编码器SDL_MOUSEWHEEL事件滚轮 y 增量取反后写入enc_diff即“向下滚 正向旋转”SDL_BUTTON_MIDDLE鼠标中键按下/释放映射为编码器的按下/释放状态mousewheel_read()每次读取后把enc_diff清零返回false表示无缓冲数据。对应的 keyboard.c 则把 SDL 键码转换为 LVGL 的LV_KEY_RIGHT / LV_KEY_LEFT / LV_KEY_UP / LV_KEY_DOWN / LV_KEY_ENTER / LV_KEY_ESC等标准键。这意味着在模拟器里用滚轮 鼠标中键或在真实硬件上用键盘方向键 回车就能完整走一遍该演示。在 HoloCubic 等嵌入式项目中的落地参考HoloCubic 固件工程位于 2.Firmware/HoloCubic-fw其中 lv_port_indev.c 给出了真实设备上注册编码器驱动的标准模板lv_indev_drv_init(indev_drv); indev_drv.type LV_INDEV_TYPE_ENCODER; indev_drv.read_cb encoder_read; indev_encoder lv_indev_drv_register(indev_drv);真实硬件场景下只需在encoder_read()中填充data-enc_diff累计旋转步数与data-state按下/释放并在中断服务函数encoder_handler()里累加步数、记录按键状态——这正是本演示在模拟器中所做事情的硬件版。从源码结构可以推断该演示与平台无关它只依赖lv_drivers提供的read_cb接口任何能输出“左右步数 按钮状态”的硬件旋转编码器、游戏手柄拨盘、滚轮等都能无缝接入。常见问题与注意事项宏不生效LV_USE_DEMO_KEYPAD_AND_ENCODER必须在编译期置 1且需要把lv_demo_keypad_encoder.c纳入编译可通过lv_examples.h统一包含头文件见 lv_examples.h本仓库中该演示与 HoloCubic 主固件默认是关闭状态。必须先有显示驱动lv_indev_drv_register内部依赖默认显示器见 lv_hal_indev.c务必在lv_init()与显示、输入驱动初始化之后再调用演示入口。编辑模式与长按对文本框、微调框等可编辑控件编码器需通过长按 Enter代码中为lv_group_set_editing的切换逻辑进入编辑模式后旋转才用于修改数值/选择字符短按 Enter 仍是“确认/按下”这是初次上手最易困惑的交互差异。模拟器依赖若要在 Windows 模拟器中体验键盘/滚轮控制需要同时打开LV_EX_KEYBOARD与LV_EX_MOUSEWHEEL两个辅助宏并链接lv_drivers工程中的键盘与鼠标滚轮驱动。以上内容全部以当前仓库实际源码与配置为准LVGL v7.6.1读者可直接打开 演示源码 逐行对照或参考 HoloCubic 固件的输入设备移植模板 将这套交互范式落地到自己的编码器硬件上。赞分享嵌入式物联网智能硬件嵌入式GUI硬件开发【免费下载链接】HoloCubic带网络功能的伪全息透明显示桌面站项目地址https://gitcode.com/gh_mirrors/ho/HoloCubic点击查看免费下载相关推荐wechat-bot 让微信 AI 自动回复从扫码登录到群值班的 20 分钟教程wechat bot 让微信 AI 自动回复从扫码登录到群值班的 20 分钟教程 五百人的工作群里一条重要通知一分钟就被刷走等你打开手机话题已经翻篇十楼AI 应用人工智能AI Agent即时通讯上一篇如何在不同系统上正确安装 Cursor AI完整指南下一篇Music Tag Web高级搜索功能利用正则表达式精准定位音乐文件创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考