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;              /* 返回键值 */
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/603306.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2023年全国职业院校技能大赛(高职组)“云计算应用”赛项赛卷4

某企业根据自身业务需求&#xff0c;实施数字化转型&#xff0c;规划和建设数字化平台&#xff0c;平台聚焦“DevOps开发运维一体化”和“数据驱动产品开发”&#xff0c;拟采用开源OpenStack搭建企业内部私有云平台&#xff0c;开源Kubernetes搭建云原生服务平台&#xff0c;选…

SpringDoc注解解析

一、什么是SpringDoc SpringDoc注解的使用&#xff0c;它是基于OpenAPI 3和Swagger 3的现代化解决方案&#xff0c;相较于旧版的Swagger2(SpringFox)&#xff0c;SpringDoc提供了更简洁、更直观的注解方式。 二、SpringDoc的注解分类 2.1 作用于类的注解 1. Tag 用于说明…

Java:爬虫htmlunit

为什么htmlunit与HttpClient两者都可以爬虫、网页采集、通过网页自动写入数据&#xff0c;我们会推荐使用htmlunit呢? 一、网页的模拟化 首先说说HtmlUnit相对于HttpClient的最明显的一个好处&#xff0c;HtmlUnit更好的将一个网页封装成了一个对象&#xff0c;如果你非要说H…

python-time模块使用

python-time模块使用 1&#xff0c;两个时间概念 struct_time: time模块的时间对象时间戳&#xff1a;从1970年1月1日到现在的秒数&#xff0c;是一个正的浮点数。 2&#xff0c; 日常使用-获取当前时间并将时间按照自己的格式生成字符串 %字符代表变量 %Y 年变量%m 月变量%d …

QT上位机开发(简易图像处理软件)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 大家都知道图像处理非常地重要&#xff0c;因为它不仅仅是可以用于拍照美颜&#xff0c;而且在工业、医疗和军事等方面也发挥着巨大的作用。另外一…

odoo16 销售模块易错的几个操作

odoo16 销售模块易错的几个操作 据168Report调研团队最新报告“全球定制服装市场报告2023-2029”显示&#xff0c;预计2029年全球定制服装市场规模将达到1082.4亿美元&#xff0c;未来几年年复合增长率CAGR为7.8%。一个普通定制的小皮袄竟月销二十多万件&#xff0c;比我们做定…

SpringBoot-项目引入Redis依赖

在使用Spring Boot开发应用时&#xff0c;可以使用Redis来实现缓存、分布式锁等功能。在编写业务逻辑代码时&#xff0c;可以通过注入RedisTemplate或StringRedisTemplate对象来操作Redis&#xff0c;如存取数据、设置过期时间、删除数据等。同时&#xff0c;还可以使用Redis的…

基于原子搜索算法优化的Elman神经网络数据预测 - 附代码

基于原子搜索算法优化的Elman神经网络数据预测 - 附代码 文章目录 基于原子搜索算法优化的Elman神经网络数据预测 - 附代码1.Elman 神经网络结构2.Elman 神经用络学习过程3.电力负荷预测概述3.1 模型建立 4.基于原子搜索优化的Elman网络5.测试结果6.参考文献7.Matlab代码 摘要&…

力扣-35. 搜索插入位置

文章目录 力扣题目两种解题思路二分查找自己的解题方法--简单易懂 力扣题目 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) …

7+非肿瘤+WGCNA+机器学习+诊断模型,构思巧妙且操作简单

今天给同学们分享一篇生信文章“Platelets-related signature based diagnostic model in rheumatoid arthritis using WGCNA and machine learning”&#xff0c;这篇文章发表在Front Immunol期刊上&#xff0c;影响因子为7.3。 结果解读&#xff1a; DEGs和血小板相关基因的…

VScode 画图插件

开源免费的插件 随着http://draw.io开源vs code插件之后&#xff0c;它一跃成为最强大的流程图工具。 目前http://draw.io支持3种文件后缀&#xff0c;你只需要新建3种后缀之一的文件就可以在vs code中画流程图&#xff0c;它们分别是&#xff1a; *.drawio*.dio*.drawio.sv…

大模型实战营Day1 书生·浦语大模型全链路开源体系

1.大模型为发展通用人工智能的重要途经 专用模型&#xff1a;针对特定任务解决特定问题 通用大模型&#xff1a;一个模型对应多模态多任务 2.InternLM大模型开源历程 3.InternLM-20B大模型性能 4.从模型到应用&#xff1a;智能客服、个人助手、行业应用 5.书生浦语全链条开源…

DynaForm 各版本安装指南

DynaForm下载链接 https://pan.baidu.com/s/1AgsSyjgRi-y0ujRwSwXtHQ?pwd0531 1.鼠标右击【DynaForm5.9.4(64bit)】压缩包&#xff08;win1及以上系统需先点击“显示更多选项”&#xff09;选择【解压到 DynaForm5.9.4(64bit)】。 2.打开解压后的文件夹&#xff0c;鼠标右击…

Vue基础 - v-bind修改属性

<div id"app"> <label for"r1">修改颜色</label><input type"checkbox" v-model"use" id"r1"> <br><br> <div v-bind:class"{class1: use}"> <!--如果use为true…

C++八股学习心得.6

1.C 异常处理 异常是程序在执行期间产生的问题。C 异常是指在程序运行时发生的特殊情况 异常提供了一种转移程序控制权的方式。C 异常处理涉及到三个关键字&#xff1a;try、catch、throw。 throw: 当问题出现时&#xff0c;程序会抛出一个异常。这是通过使用 throw 关键字来…

【数据库】视图索引执行计划多表查询面试题

文章目录 一、视图1.1 概念1.2 视图与数据表的区别1.3 优点1.4 语法1.5 实例 二、索引2.1 什么是索引2.2.为什么要使用索引2.3 优缺点2.4 何时不使用索引2.5 索引何时失效2.6 索引分类2.6.1.普通索引2.6.2.唯一索引2.6.3.主键索引2.6.4.组合索引2.6.5.全文索引 三、执行计划3.1…

@RequestParam,@RequestBody和@PathVariable 区别

RequestParam&#xff0c;RequestBody和PathVariable 这三者是spring常见的接受前端数据的注解&#xff0c;那么他们分别是接受什么的前端数据呢&#xff1f; RequestParam&#xff1a;这个注解主要用于处理请求参数&#xff0c;尤其是GET请求中的查询参数和表单参数。它可以用…

群晖NAS+DMS7.0以上版本+无docker机型安装zerotier

测试机型&#xff1a;群晖synology 218play / DSM版本为7.2.1 因218play无法安装docker&#xff0c;且NAS系统已升级为7.0以上版本&#xff0c;按zerotier官网说法无法安装zerotier, 不过还是可以通过ssh终端和命令方式安装zerotier。 1、在DSM新建文件夹 用于存放zerotier脚…

Java 动态代理是什么? 怎么实现动态代理?

Java 动态代理是什么? 怎么实现动态代理&#xff1f; Java 动态代理是一种在运行时创建代理类和实例的机制&#xff0c;它允许在调用实际方法之前或之后插入自定义的逻辑。动态代理是通过 Java 反射机制实现的&#xff0c;主要利用 java.lang.reflect.Proxy 类和 InvocationH…

HUAWEI WATCH 系列 eSIM 全新开通指南来了

HUAWEI WATCH 系列手表提供了eSIM硬件能力&#xff0c;致力为用户提供更便捷、高效的通信体验。但eSIM 业务是由运营商管理并提供服务的&#xff0c;当前运营商eSIM业务集中全面恢复&#xff0c;电信已经全面恢复&#xff0c;移动大部分省份已经全面放开和多号App开通方式&…