LVGL的List控件的触摸按键和实体按键的处理
在LVGL的List控件使用过程中,虽然通过触摸按键选择item,但是有些场景需要实体按键选取item,但是LVGL 的V8.3中没有像Emwin那样有函数选择list item的函数。LVGL中List引入了Group的概念,把列表项都添加到同一个group中。然后通过更改group的焦点达到选择list item的作用。
#include "LVGL/GUI_APP/lv_mainstart.h"
#include "lvgl.h"
#include <stdio.h>
#include "./BSP/KEY/key.h"
#define scr_act_width() lv_obj_get_width(lv_scr_act())
#define scr_act_height() lv_obj_get_height(lv_scr_act())
static lv_obj_t *list; /* 定义列表 */
static lv_obj_t *list_label; /* 定义标签 */
static const lv_font_t *font; /* 定义字体 */
extern lv_indev_t * indev_keypad;
lv_obj_t* BtnUp,*BtnDn, *label;
lv_group_t * group;
static void list_btn_event_cb(lv_event_t *e)
{
lv_obj_t *list_btn = lv_event_get_target(e);
lv_label_set_text(list_label, lv_list_get_btn_text(list, list_btn));
lv_obj_add_state(list_btn, LV_STATE_FOCUS_KEY);
}
下面是另外的触摸按键的UP/Down实现选择list item

由于没有找到重新聚焦group的函数,所以另辟蹊径,在up/down的事件回调函数中下发实体按键事件中。
static void event_btn_handler(lv_event_t *e)
{
lv_obj_t* targetObj = lv_event_get_target(e);
if (targetObj == BtnUp)
{
set_virl_key(KEY1_PRES);
}
if (targetObj == BtnDn)
{
set_virl_key(KEY0_PRES);
}
}
static void lv_example_list(void)
{
/* 根据屏幕大小设置字体 */
if (scr_act_width() <= 320)
{
font = &lv_font_montserrat_14;
}
else if (scr_act_width() <= 480)
{
font = &lv_font_montserrat_16;
}
else
{
font = &lv_font_montserrat_18;
}
/* 创建左侧矩形背景 */
lv_obj_t* obj_left = lv_obj_create(lv_scr_act()); /* 创建一个基础对象 */
lv_obj_set_width(obj_left, scr_act_width() * 0.7); /* 设置宽度 */
lv_obj_set_height(obj_left, scr_act_height() * 0.9); /* 设置高度 */
lv_obj_align(obj_left, LV_ALIGN_LEFT_MID, 5, 0); /* 设置位置 */
lv_obj_update_layout(obj_left); /* 手动更新物体的参数 */
/* 创建右侧矩形背景 */
lv_obj_t* obj_right = lv_obj_create(lv_scr_act()); /* 创建一个基础对象 */
lv_obj_set_width(obj_right, scr_act_width() - lv_obj_get_width(obj_left) - 15); /* 设置宽度 */
lv_obj_set_height(obj_right, lv_obj_get_height(obj_left)); /* 设置高度 */
lv_obj_align_to(obj_right, obj_left, LV_ALIGN_OUT_RIGHT_MID, 5, 0); /* 设置位置 */
lv_obj_update_layout(obj_right); /* 手动更新物体的参数 */
/* 显示当前选项的文本内容 */
list_label = lv_label_create(obj_right); /* 创建标签 */
lv_obj_set_width(list_label, lv_obj_get_width(obj_right) - 13); /* 设置标签的宽度 */
lv_obj_align(list_label, LV_ALIGN_TOP_MID, 0, 5); /* 设置标签位置 */
lv_obj_update_layout(list_label); /* 手动更新标签的参数 */
lv_obj_set_style_text_align(list_label, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN); /* 设置标签文本对齐方式 */
lv_label_set_text(list_label, "New"); /* 设置标签文本 */
lv_obj_set_style_text_font(list_label, font, LV_PART_MAIN); /* 设置标签文本字体 */
//
BtnUp = lv_btn_create(obj_right);
lv_obj_set_size(BtnUp, 100, 50);
lv_obj_align(BtnUp, LV_ALIGN_TOP_RIGHT, -20, 100);
// lv_obj_add_flag( BtnUp, LV_OBJ_FLAG_CHECKABLE );
lv_obj_add_event_cb(BtnUp, event_btn_handler,LV_EVENT_CLICKED,NULL);
label = lv_label_create(BtnUp); //创建label
lv_label_set_text(label, "Up"); //设置label的字内容
lv_obj_center(label); //居中对象
BtnDn = lv_btn_create(obj_right);
lv_obj_set_size(BtnDn, 100, 50);
lv_obj_align(BtnDn, LV_ALIGN_BOTTOM_RIGHT, -20, -100);
// lv_obj_add_flag( BtnDn, LV_OBJ_FLAG_CHECKABLE );
lv_obj_add_event_cb(BtnDn, event_btn_handler, LV_EVENT_CLICKED, NULL);
label = lv_label_create(BtnDn); //创建label
lv_label_set_text(label, "Down"); //设置label的字内容
lv_obj_center(label);
///
/* 创建列表 */
list = lv_list_create(obj_left); /* 创建列表 */
lv_obj_set_width(list, lv_obj_get_width(obj_left) * 0.8); /* 设置列表宽度 */
lv_obj_set_height(list, lv_obj_get_height(obj_left) * 0.9); /* 设置列表高度 */
lv_obj_center(list); /* 设置列表的位置 */
lv_obj_set_style_text_font(list, font, LV_PART_MAIN); /* 设置字体 */
/* 为列表添加按钮 */
lv_obj_t* btn;
group = lv_group_create();
lv_indev_set_group(indev_keypad, group);
lv_list_add_text(list, "File"); /* 添加列表文本 */
btn = lv_list_add_btn(list, LV_SYMBOL_FILE, "New"); /* 添加按钮 */
lv_obj_add_event_cb(btn, list_btn_event_cb, LV_EVENT_CLICKED, NULL); /* 添加按钮回调 */
lv_group_add_obj(group, btn);
label = lv_label_create(btn); //创建label
lv_label_set_text(label, "Down"); //设置label的字内容
lv_obj_center(label);
btn = lv_list_add_btn(list, LV_SYMBOL_DIRECTORY, "Open"); /* 添加按钮 */
lv_obj_add_event_cb(btn, list_btn_event_cb, LV_EVENT_CLICKED, NULL); /* 添加按钮回调 */
lv_group_add_obj(group, btn);
btn = lv_list_add_btn(list, LV_SYMBOL_SAVE, "Save"); /* 添加按钮 */
lv_obj_add_event_cb(btn, list_btn_event_cb, LV_EVENT_CLICKED, NULL); /* 添加按钮回调 */
lv_group_add_obj(group, btn);
btn = lv_list_add_btn(list, LV_SYMBOL_CLOSE, "Delete"); /* 添加按钮 */
lv_obj_add_event_cb(btn, list_btn_event_cb, LV_EVENT_CLICKED, NULL); /* 添加按钮回调 */
lv_group_add_obj(group, btn);
btn = lv_list_add_btn(list, LV_SYMBOL_EDIT, "Edit"); /* 添加按钮 */
lv_obj_add_event_cb(btn, list_btn_event_cb, LV_EVENT_CLICKED, NULL); /* 添加按钮回调 */
lv_group_add_obj(group, btn);
lv_list_add_text(list, "Connectivity"); /* 添加列表文本 */
btn = lv_list_add_btn(list, LV_SYMBOL_BLUETOOTH, "Bluetooth"); /* 添加按钮 */
lv_obj_add_event_cb(btn, list_btn_event_cb, LV_EVENT_CLICKED, NULL); /* 添加按钮回调 */
lv_group_add_obj(group, btn);
btn = lv_list_add_btn(list, LV_SYMBOL_GPS, "Navigation"); /* 添加按钮 */
lv_obj_add_event_cb(btn, list_btn_event_cb, LV_EVENT_CLICKED, NULL); /* 添加按钮回调 */
lv_group_add_obj(group, btn);
btn = lv_list_add_btn(list, LV_SYMBOL_USB, "USB"); /* 添加按钮 */
lv_obj_add_event_cb(btn, list_btn_event_cb, LV_EVENT_CLICKED, NULL); /* 添加按钮回调 */
lv_group_add_obj(group, btn);
btn = lv_list_add_btn(list, LV_SYMBOL_BATTERY_FULL, "Battery"); /* 添加按钮 */
lv_obj_add_event_cb(btn, list_btn_event_cb, LV_EVENT_CLICKED, NULL); /* 添加按钮回调 */
lv_group_add_obj(group, btn);
lv_list_add_text(list, "Exit"); /* 添加列表文本 */
btn = lv_list_add_btn(list, LV_SYMBOL_OK, "Apply"); /* 添加按钮 */
lv_group_add_obj(group, btn);
lv_obj_add_event_cb(btn, list_btn_event_cb, LV_EVENT_CLICKED, NULL); /* 添加按钮回调 */
btn = lv_list_add_btn(list, LV_SYMBOL_CLOSE, "Close"); /* 添加按钮 */
lv_obj_add_event_cb(btn, list_btn_event_cb, LV_EVENT_CLICKED, NULL); /* 添加按钮回调 */
lv_group_add_obj(group, btn);
}
注意在添加实体按键group时需要注意变量的声明的先后顺序。在lv_port_indev_template.C中初始化实体按键后,不能立即添加组,除非需要被添加的obj已经声明赋值,否则就会错误死机。在例程中的
/* 接着你需要用 `lv_group_t * group = lv_group_create()` 来创建组
* 用 `lv_group_add_obj(group, obj)` 往组中添加物体
* 并将这个输入设备分配到组中,以导航到它:
* `lv_indev_set_group(indev_keypad, group);` */
当把注释取消后就是死机,无法找到原因,后来才发现,obj还没有声明赋值
void lv_mainstart(void)
{
lv_example_list();
}
在key.c中添加按键和虚拟触摸按键的处理。
void set_virl_key(uint8_t key)
{
vir_key = key;
}
uint8_t key_scan(uint8_t mode)
{
static uint8_t key_up = 1; /* 按键按松开标志 */
uint8_t keyval = 0;
if (mode) key_up = 1; /* 支持连按 */
if (key_up && (KEY0 == 0 || KEY1 == 0 || KEY2 == 0 || WK_UP == 1)) /* 按键松开标志为1, 且有任意一个按键按下了 */
{
delay_ms(10); /* 去抖动 */
key_up = 0;
if (KEY0 == 0) keyval = KEY0_PRES;
if (KEY1 == 0) keyval = KEY1_PRES;
if (KEY2 == 0) keyval = KEY2_PRES;
if (WK_UP == 1) keyval = WKUP_PRES;
}
else if(vir_key!=0)
{
keyval = vir_key;
vir_key = 0;
}
else if (KEY0 == 1 && KEY1 == 1 && KEY2 == 1 && WK_UP == 0) /* 没有任何按键按下, 标记按键松开 */
{
key_up = 1;
}
return keyval; /* 返回键值 */
}
相关文章:
LVGL的List控件的触摸按键和实体按键的处理
在LVGL的List控件使用过程中,虽然通过触摸按键选择item,但是有些场景需要实体按键选取item,但是LVGL 的V8.3中没有像Emwin那样有函数选择list item的函数。LVGL中List引入了Group的概念,把列表项都添加到同一个group中。然后通过更…...
数据结构 模拟实现二叉树(孩子表示法)
目录 一、二叉树的简单概念 (1)关于树的一些概念 (2)二叉树的一些概念及性质 定义二叉树的代码: 二、二叉树的方法实现 (1)createTree (2)preOrder (…...
Android14之解决刷机报错:Can not load Android system. Your data may be corrupt(一百七十七)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…...
二阶贝塞尔曲线生成弧线
概述 本文分享一个二阶贝塞尔曲线曲线生成弧线的算法。 效果 实现 1. 封装方法 class ArcLine {constructor(from, to, num 100) {this.from from;this.to to;this.num num;return this.getPointList();}getPointList() {const { from, to } thisconst ctrlPoint thi…...
FilterQuery过滤查询
ES中的查询操作分为两种:查询和过滤。查询即是之前提到的query查询,它默认会计算每个返回文档的得分,然后根据得分排序。而过滤只会筛选出符合条件的文档,并不计算得分,并且可以缓冲记录。所以我们在大范围筛选数据时&…...
java多线程(并发)夯实之路-线程池深入浅出
线程池 Thread Pool:线程池,存放可以重复使用的线程(消费者) Blocking Queue:阻塞队列,存放等待执行的任务(生产者) poll方法(有时限地获取任务)相对take注…...
数据库-列的类型-字符串char类型
char 和 varchar 类型 char 类型懂得都懂就是固定的字符串类型 char (maxLen) 例如 char(5) 这个长度为5 但插入数据‘a’时 是5 插入abc 也是5 即使插满固定 就像C/C语言里 char 字符数组一样 char str[64]; maxLen255 哈哈最多有255个字符多了我认为你是错误 varchar…...
大话 JavaScript(Speaking JavaScript):第二十一章到第二十五章
第二十一章:数学 原文:21. Math 译者:飞龙 协议:CC BY-NC-SA 4.0 Math对象用作多个数学函数的命名空间。本章提供了一个概述。 数学属性 Math的属性如下: Math.E 欧拉常数(e) Math.LN2 2 …...
ICMP协议
ICMP协议是网络层协议, 利用ICMP协议可以实现网络中监听服务和拒绝服务,如 ICMP重定向的攻击。 一、ICMP基本概念 1、ICMP协议 ICMP是Internet控制报文协议,用于在IP主机、路由器之间传递控制消息,控制消息指网络通不通、主机是…...
环信服务端下载消息文件---菜鸟教程
前言 在服务端,下载消息文件是一个重要的功能。它允许您从服务器端获取并保存聊天消息、文件等数据,以便在本地进行进一步的处理和分析。本指南将指导您完成环信服务端下载消息文件的步骤。 环信服务端下载消息文件是指在环信服务端上,通过调…...
创建型模式 | 建造者模式
一、建造者模式 1、原理 建造者模式又叫生成器模式,是一种对象的构建模式。它可以将复杂对象的建造过程抽象出来,使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象。创建者模式是一步一步创建一个复杂的对象…...
MVC设计模式
在当今的软件开发领域,MVC(Model-View-Controller)设计模式已经成为了一种广泛使用的架构模式。它为应用程序提供了一种结构化的方法,将数据、用户界面和业务逻辑分开,从而使得应用程序更易于维护、扩展和重用。 一、…...
WSL (2103) ERROR: CreateProcessEntryCommon:493: chdir 错误解决
[TOC](WSL (2103) ERROR: CreateProcessEntryCommon:493: chdir 错误解决) 1. 错误信息 <3>WSL (2103) ERROR: CreateProcessEntryCommon:493: chdir(/mnt/d/Program Files/PowerShell/7) failed 52. 解决方法 wsl --shutdownwslrefer: https://github.com/microsoft/…...
【二、自动化测试】为什么要做自动化测试?哪种项目适合做自动化?
自动化测试是一种软件测试方法,通过编写和使用自动化脚本和工具,以自动执行测试用例并生成结果。 自动化旨在替代手动测试过程,提高测试效率和准确性。 自动化测试可以覆盖多种测试类型,包括功能测试、性能测试、安全测试等&…...
用ChatGPT来造一个ChatGPT:计算机领域智能问答系统实践(2)
在PHP语言中,你可以使用MySQL数据库来存储知识库,并使用PHP来实现系统的逻辑。以下是一个简单的示例: 创建数据库表: 首先,创建一个名为 computer_knowledge 的表来存储计算机知识。可以使用以下SQL语句:…...
Ubuntu开机自动挂载硬盘
前言: 因为我的电脑是WIN10 Ubuntu18.04双系统,且两个系统都装在C盘上,而D盘作为数据和代码存储盘,经常会开机就被访问,例如上一次关机前用VS Code访问D盘代码,然后下一次开机的时候打开VSCode发现打不开…...
vue3基础:单文件组件介绍
介绍 Vue 的单文件组件 (即 *.vue 文件,简称 SFC,全称是single file component) 是一种特殊的文件格式,使我们能够将一个 Vue 组件的模板、逻辑与样式封装在单个文件中。下面是一个单文件组件的示例: <script> export def…...
OCR字符识别:开始批量识别身份证信息
身份证信息批量识别OCR是一项解决方案,它能够将身份证照片打包成zip格式或通过URL地址进行提交,并能够识别照片中的文本信息。最终,用户可以将识别结果生成为excel文件进行下载。 API接口功能: 1. 批量识别:支持将多…...
php多小区智慧物业管理系统源码带文字安装教程
多小区智慧物业管理系统源码带文字安装教程 运行环境 服务器宝塔面板 PHP 7.0 Mysql 5.5及以上版本 Linux Centos7以上 统计分析以小区为单位,统计如下数据:小区总栋数、小区总户数、小区总人数、 小区租户数量、小区每月收费金额统计、小区车位统计、小…...
解决虚拟机的网络图标不见之问题
在WIN11中,启动虚拟机后,发现网络图标不见了,见下图: 1、打开虚拟机终端 输入“sudo server network-manager stop”,停止网络管理器 输入“cd /回车” , 切换到根目录 输入“cd var回车” ,…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...
