当前位置: 首页 > news >正文

LVGL4种输入设备详解(触摸、键盘、实体按键、编码器)

lvgl有触摸、键盘、实体按键、编码器四种输入设备

先来分析一下这四种输入设备有什么区别

(1)LV_INDEV_TYPE_POINTER

主要用于触摸屏

用到哪个输入设备保留哪个其他的也是,保留触摸屏输入的任务注册,其它几种种输入任务的注册,注释掉

添加自己触摸函数

(2)LV_INDEV_TYPE_KEYPAD

要使用键盘或者编码器必须将创建个组,具体参考编码器

  • 必须创建一个对象组:并且必须使用lv_group_t * g = lv_group_create()

  • 将对象添加到组中lv_group_add_obj(g, obj)

  • 创建的组必须分配给输入设备:lv_indev_set_group(my_indev, g)

它的输入处理函数keypad_read中,就根据输入的不同按键(LV_KEY_UP,LV_KEY_DOWN,LV_KEY_LEFT,LV_KEY_RIGHT,LV_KEY_ENTER等)对Keypad所绑定的group内的组件进行操作,如焦点的切换、进度条的滑动。比如说对于一个Table来说,里面的数据很多,有一个滑动条,这个滑动条就受LV_KEY_UP和LV_KEY_DOWN键控制;而对于一个Tabview来说,Tab的切换则是受LV_KEY_LEFT和LV_KEY_RIGHT键控制。而Group中的组件之间的焦点切换则是通过LV_KEY_PREV和LV_KEY_NEXT键切换。

(3)LV_INDEV_TYPE_BUTTON

就是一个实体按键,适用于GUI中焦点永远在某一个组件上的情况。按下物理按键就代表GUI中的按键按下。

修改成按钮实际坐标

添加按键按下函数

(4)LV_INDEV_TYPE_ENCODER

使用编码器,您可以执行以下操作:

  1. 按下它的按钮

  2. 长按其按钮

  3. 左转

  4. 右转

简而言之,Encoder 输入设备的工作原理如下:

  • 通过转动编码器,您可以专注于下一个/上一个对象。

  • 当您在简单对象(如按钮)上按下编码器时,它将被单击。

  • 如果您在复杂对象(如列表、消息框等)上按下编码器,该对象将进入编辑模式,您可以通过转动编码器在对象内导航。

  • 要退出编辑模式,请长按按钮。

组的创建

从注释可以知道要使用键盘或者编码器必须将创建个组

可以使用自定义组和默认组

自定义组创建过程

  • 必须创建一个对象组:并且必须使用lv_group_t * g = lv_group_create()

  • 将对象添加到组中lv_group_add_obj(g, obj)

  • 创建的组必须分配给输入设备:lv_indev_set_group(my_indev, g)

以滑块为例

红色为聚焦时的状态,这个状态左旋右旋可以修改滑块值和检测按键按下

在lv_port.c中使用编码器

可以在用到的地方创建自定义组,那样可以不用声明组,但要声明输入设备

extern lv_indev_t * indev_encoder;
static lv_obj_t * slider1_label;
static lv_obj_t * slider2_label;
static lv_obj_t * slider3_label;
static lv_obj_t * slider4_label;static void slider_event_cb(lv_event_t * e)
{lv_obj_t * slider = lv_event_get_target(e);int value = lv_slider_get_value(slider);char buf[8];lv_snprintf(buf, sizeof(buf), "%d%%", value);// 根据滑块更新对应的标签if (slider == lv_obj_get_child(lv_scr_act(), 0)) {lv_label_set_text(slider1_label, buf);} else if (slider == lv_obj_get_child(lv_scr_act(), 2)) {lv_label_set_text(slider2_label, buf);} else if (slider == lv_obj_get_child(lv_scr_act(), 4)) {lv_label_set_text(slider3_label, buf);} else if (slider == lv_obj_get_child(lv_scr_act(), 6)) {lv_label_set_text(slider4_label, buf);}
}void lv_example_slider_1(void)
{/* 创建第一个滑块 */lv_obj_t * slider1 = lv_slider_create(lv_scr_act());lv_obj_set_size(slider1, 200, 10);  // 设置滑块的大小lv_obj_align(slider1, LV_ALIGN_TOP_MID, 0, 20);  // 将第一个滑块对齐到顶部中间lv_obj_add_event_cb(slider1, slider_event_cb, LV_EVENT_VALUE_CHANGED, NULL);/* 创建第一个滑块的标签 */slider1_label = lv_label_create(lv_scr_act());lv_label_set_text(slider1_label, "0%");lv_obj_align_to(slider1_label, slider1, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);/* 创建第二个滑块 */lv_obj_t * slider2 = lv_slider_create(lv_scr_act());lv_obj_set_size(slider2, 200, 10);  // 设置滑块的大小lv_obj_align(slider2, LV_ALIGN_TOP_MID, 0, 80);  // 将第二个滑块对齐到第一个滑块下方lv_obj_add_event_cb(slider2, slider_event_cb, LV_EVENT_VALUE_CHANGED, NULL);/* 创建第二个滑块的标签 */slider2_label = lv_label_create(lv_scr_act());lv_label_set_text(slider2_label, "0%");lv_obj_align_to(slider2_label, slider2, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);/* 创建第三个滑块 */lv_obj_t * slider3 = lv_slider_create(lv_scr_act());lv_obj_set_size(slider3, 200, 10);  // 设置滑块的大小lv_obj_align(slider3, LV_ALIGN_TOP_MID, 0, 140);  // 将第三个滑块对齐到第二个滑块下方lv_obj_add_event_cb(slider3, slider_event_cb, LV_EVENT_VALUE_CHANGED, NULL);/* 创建第三个滑块的标签 */slider3_label = lv_label_create(lv_scr_act());lv_label_set_text(slider3_label, "0%");lv_obj_align_to(slider3_label, slider3, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);/* 创建第四个滑块 */lv_obj_t * slider4 = lv_slider_create(lv_scr_act());lv_obj_set_size(slider4, 200, 10);  // 设置滑块的大小lv_obj_align(slider4, LV_ALIGN_TOP_MID, 0, 200);  // 将第四个滑块对齐到第三个滑块下方lv_obj_add_event_cb(slider4, slider_event_cb, LV_EVENT_VALUE_CHANGED, NULL);/* 创建第四个滑块的标签 */slider4_label = lv_label_create(lv_scr_act());lv_label_set_text(slider4_label, "0%");lv_obj_align_to(slider4_label, slider4, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);/* 创建 group */lv_group_t * group = lv_group_create();// 将滑块添加到组中lv_group_add_obj(group, slider1);lv_group_add_obj(group, slider2);lv_group_add_obj(group, slider3);lv_group_add_obj(group, slider4);// 将 group 绑定到输入设备(假设 indev_encoder 已初始化)lv_indev_set_group(indev_encoder, group);
}

使用默认组

对于一些比较复杂的组件使用默认组可以很方便

  • 在lvgl中有些部件,在创建的时候加入到默认组中,但是默认组变量lvgl并没有帮助我们初始化好,我们需要在创建部件之前初始化好才能使用默认组,这个自定义组一样不同的是对于创建时添加:

lv_group_t * g = lv_group_create(); // 创建一个组
lv_group_set_default(g);             // 设置为默认组

之后在需要的地方获取和绑定默认组

/* 获取group */
lv_group_t * group = lv_group_get_default();// 将 group 绑定到输入设备
lv_indev_set_group(indev_encoder, group);

以tabview为例

可以在这里创建默认组

extern lv_indev_t * indev_encoder;
static lv_obj_t * slider1_label;
static lv_obj_t * slider2_label;
static lv_obj_t * slider3_label;
static lv_obj_t * slider4_label;static void slider_event_cb(lv_event_t * e)
{lv_obj_t * slider = lv_event_get_target(e);int value = lv_slider_get_value(slider);char buf[8];lv_snprintf(buf, sizeof(buf), "%d%%", value);// 根据滑块更新对应的标签if (slider == lv_obj_get_child(lv_scr_act(), 0)) {lv_label_set_text(slider1_label, buf);} else if (slider == lv_obj_get_child(lv_scr_act(), 2)) {lv_label_set_text(slider2_label, buf);} else if (slider == lv_obj_get_child(lv_scr_act(), 4)) {lv_label_set_text(slider3_label, buf);} else if (slider == lv_obj_get_child(lv_scr_act(), 6)) {lv_label_set_text(slider4_label, buf);}
}void lv_example_slider_1(void)
{/* 创建第一个滑块 */lv_obj_t * slider1 = lv_slider_create(lv_scr_act());lv_obj_set_size(slider1, 200, 10);  // 设置滑块的大小lv_obj_align(slider1, LV_ALIGN_TOP_MID, 0, 20);  // 将第一个滑块对齐到顶部中间lv_obj_add_event_cb(slider1, slider_event_cb, LV_EVENT_VALUE_CHANGED, NULL);/* 创建第一个滑块的标签 */slider1_label = lv_label_create(lv_scr_act());lv_label_set_text(slider1_label, "0%");lv_obj_align_to(slider1_label, slider1, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);/* 创建第二个滑块 */lv_obj_t * slider2 = lv_slider_create(lv_scr_act());lv_obj_set_size(slider2, 200, 10);  // 设置滑块的大小lv_obj_align(slider2, LV_ALIGN_TOP_MID, 0, 80);  // 将第二个滑块对齐到第一个滑块下方lv_obj_add_event_cb(slider2, slider_event_cb, LV_EVENT_VALUE_CHANGED, NULL);/* 创建第二个滑块的标签 */slider2_label = lv_label_create(lv_scr_act());lv_label_set_text(slider2_label, "0%");lv_obj_align_to(slider2_label, slider2, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);/* 创建第三个滑块 */lv_obj_t * slider3 = lv_slider_create(lv_scr_act());lv_obj_set_size(slider3, 200, 10);  // 设置滑块的大小lv_obj_align(slider3, LV_ALIGN_TOP_MID, 0, 140);  // 将第三个滑块对齐到第二个滑块下方lv_obj_add_event_cb(slider3, slider_event_cb, LV_EVENT_VALUE_CHANGED, NULL);/* 创建第三个滑块的标签 */slider3_label = lv_label_create(lv_scr_act());lv_label_set_text(slider3_label, "0%");lv_obj_align_to(slider3_label, slider3, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);/* 创建第四个滑块 */lv_obj_t * slider4 = lv_slider_create(lv_scr_act());lv_obj_set_size(slider4, 200, 10);  // 设置滑块的大小lv_obj_align(slider4, LV_ALIGN_TOP_MID, 0, 200);  // 将第四个滑块对齐到第三个滑块下方lv_obj_add_event_cb(slider4, slider_event_cb, LV_EVENT_VALUE_CHANGED, NULL);/* 创建第四个滑块的标签 */slider4_label = lv_label_create(lv_scr_act());lv_label_set_text(slider4_label, "0%");lv_obj_align_to(slider4_label, slider4, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);/* 创建 group */lv_group_t * group = lv_group_create();// 将滑块添加到组中lv_group_add_obj(group, slider1);lv_group_add_obj(group, slider2);lv_group_add_obj(group, slider3);lv_group_add_obj(group, slider4);// 将 group 绑定到输入设备(假设 indev_encoder 已初始化)lv_indev_set_group(indev_encoder, group);
}

实现获取编码器增量值和判断编码器是否按下

参考官方文档

实现获取编码器增量值和判断编码器是否按下 

相关文章:

LVGL4种输入设备详解(触摸、键盘、实体按键、编码器)

lvgl有触摸、键盘、实体按键、编码器四种输入设备 先来分析一下这四种输入设备有什么区别 (1)LV_INDEV_TYPE_POINTER 主要用于触摸屏 用到哪个输入设备保留哪个其他的也是,保留触摸屏输入的任务注册,其它几种种输入任务的注册&…...

全流程安装DeepSeek开源模型

目录 配置要求安装Ollama选择大模型安装大模型对话备注 配置要求 我的电脑配置为: CPU:i7 12代 GPU:3080 内存:32g 磁盘:1T以上配置运行情况: 运行ollama run deepseek-r1:7b模型无压力,CPU/…...

人工智能领域-CNN 卷积神经网络 性能调优

在自动驾驶领域,对卷积神经网络(CNN)进行性能调优至关重要,以下从数据处理、模型架构、训练过程、超参数调整和模型部署优化等多个方面为你详细介绍调优方法,并给出相应的代码示例。 1. 数据处理 数据增强&#xff1…...

人工智能A*算法与CNN结合- CNN 增加卷积层的数量,并对卷积核大小进行调整

以下是一个增强版的将 A* 算法与卷积神经网络(CNN)结合的代码实现,其中 CNN 增加了卷积层的数量,并对卷积核大小进行了调整。整体思路依然是先利用 A* 算法生成训练数据,再用这些数据训练 CNN 模型,最后使用…...

机器学习中常用的评价指标

一、分类任务常用指标 1. 准确率(Accuracy) 定义:正确预测样本数占总样本数的比例。优点:直观易懂,适用于类别平衡的数据。缺点:对类别不平衡数据敏感(如欺诈检测中99%的负样本)。…...

Windows安装cwgo,一直安装的是linux平台的

Windows安装cwgo,一直安装的是linux平台的 查看 go env ,发现 GOOSlinux 临时修改 GOOS ,set GOOSwindows ,再安装。 此时,安装的就是 windows 的可执行文件。安装之后再将 GOOS 修改回来即可。...

GitHub Pages + Jekyll 博客搭建指南(静态网站)

目录 🚀 静态网站及其生成工具指南🌍 什么是静态网站?📌 静态网站的优势⚖️ 静态网站 VS 动态网站 🚀 常见的静态网站生成器对比🛠️ 使用 GitHub Pages Jekyll 搭建个人博客📌 1. 创建 GitHu…...

21.[前端开发]Day21-HTML5新增内容-CSS函数-BFC-媒体查询

王者荣耀-网页缩小的问题处理 为什么会产生这个问题?怎么去解决 可以给body设置最小宽度 1 HTML5新增元素 HTML5语义化元素 HTML5其他新增元素 2 Video、Audio元素 HTML5新增元素 - video video支持的视频格式 video的兼容性写法 HTML5新增元素 - audio audio…...

C++SLT(五)——list

目录 一、list的介绍二、list的使用list的定义方式 三、list的插入和删除push_back和pop_backpush_front和pop_frontinserterase 四、list的迭代器使用五、list的元素获取六、list的大小控制七、list的操作函数sort和reversemergeremoveremove_ifuniqueassignswap 一、list的介…...

网络安全ITP是什么 网络安全产品ips

DS/IPS都是专门针对计算机病毒和黑客入侵而设计的网络安全设备 1、含义不同 IDS :入侵检测系统(发现非法入侵只能报警不能自己过滤) 做一个形象的比喻:假如防火墙是一幢大楼的门锁,那么IDS就是这幢大楼里的监视系统…...

评估大模型(LLM)摘要生成能力:方法、挑战与策略

大语言模型(LLMs)有着强大的摘要生成能力,为信息快速提取和处理提供了便利。从新闻文章的快速概览到学术文献的要点提炼,LLMs 生成的摘要广泛应用于各个场景。然而,准确评估这些摘要的质量却颇具挑战。如何确定一个摘要…...

《PYTHON语言程序设计》(2018版)1.20修改这道题,利用类的方式(二) 接近成功....(上)

在类的外面建立4个顶点 turtle.speed(20)ran1_x1 random.randint(-69, -60) ran1_y1 random.randint(-5, 10) ran1_x2 random.randint(-69, -60) ran1_y2 random.randint(75, 80) ran1_x3 random.randint(79, 90) ran1_y3 random.randint(70, 85) ran1_x4 random.randin…...

USB子系统学习(四)使用libusb读取鼠标数据

文章目录 1、声明2、HID协议2.1、描述符2.2、鼠标数据格式 3、应用程序4、编译应用程序5、测试 1、声明 本文是在学习韦东山《驱动大全》USB子系统时,为梳理知识点和自己回看而记录,全部内容高度复制粘贴。 韦老师的《驱动大全》:商品详情 …...

【产品小白】用户调研的需求是否都采纳?

在用户调研中,并非所有需求都应被直接采纳,而应通过系统分析转化为符合产品战略的有效决策。以下是关键思考框架: 1. 用户需求 ≠ 产品需求 矛盾性:用户个体需求可能相互冲突(如A功能的去留),需…...

软件测试就业

文章目录 2.6 初识一、软件测试理论二、软件的生产过程三、软件测试概述四、软件测试目的五、软件开发与软件测试的区别?六、学习内容 2.7 理解一、软件测试的定义二、软件测试的生命周期三、软件测试的原则四、软件测试分类五、软件的开发与测试模型1.软件开发模型…...

qt部分核心机制

作业 1> 手动将登录项目实现,不要使用拖拽编程 并且,当点击登录按钮时,后台会判断账号和密码是否相等,如果相等给出登录成功的提示,并且关闭当前界面,发射一个跳转信号,如果登录失败&#…...

【RocketMQ】RocketMq之ConsumeQueue深入研究

目录 一:RocketMq 整体文件存储介绍 二:ConsumeQueue 的文件结构 三:ConsumeQueue 写入和查询流程 一:RocketMq 整体文件存储介绍 存储⽂件主要分为三个部分: CommitLog:存储消息的元数据。所有消息都会…...

如今物联网的快速发展对hmi的更新有哪些积极影响

一、功能更加丰富 物联网的快速发展使得 HMI(人机界面)能够连接更多的设备和系统,从而实现更加丰富的功能。例如,通过与传感器网络的连接,HMI 可以实时显示设备的运行状态、环境参数等信息,为用户提供更加…...

linux 性能60秒分析

linux 60秒分析 需要运行的工具是 1、uptime 2、dmesg | tail 3、vmstat 1 4、mpstat -P ALL 1 5、pidstat 1 6、iostat -xz 1 7、free -m 8、sar -n DEV 1 9、sar -n TCP,ETCP 1 10、topuptime 快速检查平均负载 [rootaaaaaa ~]# uptime15:17:20 up 3 days, 14 min, 7 us…...

Redisson全面解析:从使用方法到工作原理的深度探索

文章目录 写在文章开头详解Redisson基本数据类型基础配置字符串操作列表操作映射集阻塞队列延迟队列更多关于Redisson详解Redisson 中的原子类详解redisson中的发布订阅模型小结参考写在文章开头 Redisson是基于原生redis操作指令上进一步的封装,屏蔽了redis数据结构的实现细…...

neo4j-解决导入数据后出现:Database ‘xxxx‘ is unavailable. Run :sysinfo for more info.

目录 问题描述 解决方法 重新导入 问题描述 最近在linux上部署了neo4j,参照之前写的博客:neo4j-数据的导出和导入_neo4j数据导入导出-CSDN博客 进行了数据导出、导入操作。但是在进行导入后,重新登录网页版neo4j,发现对应的数据库状态变…...

51单片机之引脚图(详解)

8051单片机引脚分类与功能笔记 1. 电源引脚 VCC(第40脚):接入5V电源,为单片机提供工作电压。GND(第20脚):接地端,确保电路的电位参考点。 2.时钟引脚 XTAL1(第19脚&a…...

Hangfire.NET:.NET任务调度

引言:为何选择 Hangfire? 在开发.NET 应用程序时,我们常常会遇到这样的场景:应用程序需要定期发送报告,像财务报表,每日业务数据汇总报告等,这些报告需要定时生成并发送给相关人员;…...

深入解析:React 事件处理的秘密与高效实践

在 React 中,事件处理是构建交互式应用的核心。本文将带你深入探索 React 事件处理的机制、最佳实践以及如何避免常见陷阱,助你写出更高效、更健壮的代码。 1. React 事件处理的独特之处 合成事件(SyntheticEvent) React 使用合…...

开源像素字体,可用于独立游戏开发

方舟像素字体 / Ark Pixel Font 开源的泛中日韩像素字体,使用 SIL 开放字体许可证 第1.1版(SIL Open Font License 1.1)授权。 支持 10、12 和 16 像素尺寸。 支持语言特殊字形:中文-中国大陆、中文-香港特别行政区、中文-台湾…...

【论文阅读】Comment on the Security of “VOSA“

Comment on the Security of Verifiable and Oblivious Secure Aggregation for Privacy-Preserving Federated Learning -- 关于隐私保护联邦中可验证与遗忘的安全聚合的安全性 论文来源摘要Introduction回顾 VOSA 方案对VOSA不可伪造性的攻击对于类型 I 的攻击对于类型 II 的…...

了解传输层TCP协议

目录 一、TCP协议段格式 二、TCP原理 1.确认应答 2.超时重传 3.连接管理 建立连接 断开连接 4.滑动窗口 5.流量控制 6.拥塞控制 7.延时应答 8.捎带应答 9.面向字节流 10.TCP异常情况 TCP,即Transmission Control Protocol,传输控制协议。人如…...

flask实现用户名查重,重复的用户名阻止注册,以及如何优化

在 Flask 中实现用户名查重,并阻止重复的用户名进行注册,可以使用数据库(如 SQLite、MySQL、PostgreSQL)存储用户信息,并在注册时检查用户名是否已存在。以下是实现步骤: 1. 安装 Flask 及 SQLAlchemy 确保…...

ASP.NET Core对JWT的封装

目录 JWT封装 [Authorize]的注意事项 JWT封装 NuGet 库 |Microsoft.AspNetCore.Authentication.JwtBearer 9.0.1https://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.JwtBearerhttps://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.JwtBea…...

wordpressAI工具,已接入Deepseek 支持自动生成文章、生成图片、生成长尾关键词、前端AI窗口互动、批量采集等

基于关键词或现有内容生成SEO优化的文章,支持多种AI服务(如OpenAI、百度文心一言、智谱AI等),并提供定时任务、内容采集、关键词生成等功能。 核心功能 文章生成 关键词生成:根据输入的关键词生成高质量文章。 内容…...