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),仅供参考

相关新闻

LAMMPS comm_modify 命令详解:精细调控幽灵原子通信,优化并行性能

LAMMPS comm_modify 命令详解:精细调控幽灵原子通信,优化并行性能

科研科学计算高性能计算 【免费下载链接】lammps Public development project of the LAMMPS MD software package 项目地址: https://gitcode.com/gh_mirrors/la/lammps 点击查看 免费下载 comm_modify 是 LAMMPS 中用于调节"处理器间原子通信"行为的核…

2026/10/15 2:32:22 阅读更多 →
阿里云服务器+phpStudy小面板:个人网站从零部署实战指南

阿里云服务器+phpStudy小面板:个人网站从零部署实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 2:32:22 阅读更多 →
TG WS Proxy贡献者指南:项目结构剖析与如何提交你的第一个PR

TG WS Proxy贡献者指南:项目结构剖析与如何提交你的第一个PR

TG WS Proxy贡献者指南:项目结构剖析与如何提交你的第一个PR TG WS Proxy 是一款免费的本地 MTProto 代理服务器,专为 Telegram Desktop 加速加载而设计。它将 Telegram 流量通过 WebSocket 连接重定向,数据全程保持加密传输,且无…

2026/10/15 2:32:22 阅读更多 →

最新新闻

笑脸与口罩识别的工业级落地:从像素统计到人机意图理解

笑脸与口罩识别的工业级落地:从像素统计到人机意图理解

1. 这不是玩具项目:笑脸与口罩识别背后的真实业务切口“笑脸识别,口罩识别”——光看标题,很多人第一反应是:这不就是个课堂Demo?调用OpenCV读个摄像头,加两行cv2.CascadeClassifier,再套个预训…

2026/10/15 3:08:36 阅读更多 →
2026,程序员的时代拐点到了

2026,程序员的时代拐点到了

1. 引言 2026 年,注定是程序员职业生涯中一个无法回避的坐标点。这一年,AI 编程助手从「玩具」变成了「同事」,大模型从「聊天机器人」变成了「需求分析师」,而程序员这个职业本身,也站在了前所未有的十字路口。有人焦…

2026/10/15 3:08:36 阅读更多 →
TensorFlow Lite集成实战:从模型转换、量化到端侧推理加速

TensorFlow Lite集成实战:从模型转换、量化到端侧推理加速

到这里,前几章我们讲了模型怎么训、怎么调,该轮到最“落地”的一步了:TensorFlow Lite集成。这章我想用一次完整的实操视角,把从训练好的模型到真正跑在端侧设备上的全流程讲透——包括模型转换、量化、Delegate加速、端侧推理API…

2026/10/15 3:08:36 阅读更多 →
Rope 免费换脸教程:从安装到导出第一条视频的 10 分钟路径

Rope 免费换脸教程:从安装到导出第一条视频的 10 分钟路径

Rope 免费换脸教程:从安装到导出第一条视频的 10 分钟路径 【免费下载链接】Rope GUI-focused roop 项目地址: https://gitcode.com/GitHub_Trending/ro/Rope Rope 是一款免费的图形化人脸交换工具,基于 insightface 的 inswapper_128&#xff08…

2026/10/15 3:08:36 阅读更多 →
金蝶Cloud销售模块参数配置全攻略:从流程打通到信用风控

金蝶Cloud销售模块参数配置全攻略:从流程打通到信用风控

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 3:08:36 阅读更多 →
免费广告拦截插件 uBlock Origin:默认 5 份过滤列表,请求发出前就拦下

免费广告拦截插件 uBlock Origin:默认 5 份过滤列表,请求发出前就拦下

免费广告拦截插件 uBlock Origin:默认 5 份过滤列表,请求发出前就拦下 【免费下载链接】uBlock uBlock Origin - An efficient blocker for Chromium and Firefox. Fast and lean. 项目地址: https://gitcode.com/GitHub_Trending/ub/uBlock 很多…

2026/10/15 3:07:36 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →