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之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...
基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...
第八部分:阶段项目 6:构建 React 前端应用
现在,是时候将你学到的 React 基础知识付诸实践,构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段,你可以先使用模拟数据,或者如果你的后端 API(阶段项目 5)已经搭建好,可以直接连…...
游戏开发中常见的战斗数值英文缩写对照表
游戏开发中常见的战斗数值英文缩写对照表 基础属性(Basic Attributes) 缩写英文全称中文释义常见使用场景HPHit Points / Health Points生命值角色生存状态MPMana Points / Magic Points魔法值技能释放资源SPStamina Points体力值动作消耗资源APAction…...
STL 2迭代器
文章目录 1.迭代器2.输入迭代器3.输出迭代器1.插入迭代器 4.前向迭代器5.双向迭代器6.随机访问迭代器7.不同容器返回的迭代器类型1.输入 / 输出迭代器2.前向迭代器3.双向迭代器4.随机访问迭代器5.特殊迭代器适配器6.为什么 unordered_set 只提供前向迭代器? 1.迭代器…...
