LVGL_基础控件timer

news2024/9/23 13:20:19

LVGL_基础控件timer

1、创建基础控件定时器

/*
下面创建三个timer,最后创建的timer会被放在timer list的最前面,
lvgl的任务处理器会从timer list从头到尾按顺序遍历检查,执行满足执行条件的timer。
因此,如果三个定时器的周期设置一样的话,那么最后创建的timer会先执行。
*/
lv_timer_t * timer;
/* 创建第一个timer */
timer = lv_timer_create(my_timer1, 500,  NULL);//定时周期500ms

//回调函数
 static void my_timer1(lv_timer_t * timer)
{
  /*获取并打印lvgl任务处理器(定时器)的空闲百分比时间*/
  LV_LOG_USER("my_timer1: timer idle %d\n", lv_timer_get_idle());
  /*如果我们只创建一个定时器,并且该定时器调用的是此函数,并且定时器执行周期是500ms,那么:*/
  //usleep(500000); // 定时器的空闲百分比接近 0%
  //usleep(250000); // 定时器的空闲百分比接近 50%
  //usleep(125000); // 定时器的空闲百分比接近 75%
  //usleep(0);      // 定时器的空闲百分比接近 100%
}

2、创建基础控件定时器方法二

lv_timer_t * timer;
/* 通过另一个接口创建第三个timer */
timer = lv_timer_create_basic();

// 修改此timer的回调函数和周期时间
lv_timer_set_cb(timer, my_timer3);//设置回调函数
lv_timer_set_period(timer, 100);//设置周期

3、创建好定时器后启动

//让定时器马上就开始执行第一次,而不是等到下一次计时周期到了才触发定时器
lv_timer_ready(timer);

4、设置定时器执行次数

// 设置此timer的运行次数,设置后该timer在执行指定次数后会自动删除
// 设置为 -1 就是无限重复,默认值就是 -1
lv_timer_set_repeat_count(timer, 3);

5、异步删除函数

/*测试2:通过异步调用删除arc*/
// 通常情况下,我们可以通过调用 lv_obj_del 当场直接删除对象
// 但是有些情况我们不能马上删除该对象,
// 我们可以在下次运行lv_task_handler()时,第一时间(最高优先级)在进行删除

/* 异步删除对象有两个接口 */
// 这个是lvgl提供的接口函数,我们只能传入想要删除的对象,该函数只能执行删除操作,
// 因为它最终也只是调用了 lv_obj_del,仅此而已。
// 所以我们想在下次运行lv_task_handler()时删除一个对象(及其所有后代)时,可以使用下面的这个函数
lv_obj_del_async(arc);

// 通过这个接口函数,我们可以传入自己的操作函数,除了删除操作之外还可以进行其他LVGL的相关操作
//lv_async_call(del_obj_async_call_cb, arc);

static void del_obj_async_call_cb(void * scr)
{
  /* 这会在下次运行 lv_task_handler() 时,第一时间(最高优先级)得到运行 */
  /* 在这里除了删除操作,还能进行其他操作 */
  // You can do something here with LVGL...

  lv_obj_del(arc);
  arc = NULL;
}

6、拓展示例
在这里插入图片描述

/* 创建一个arc组件,稍后我们会对其进行试验 */
lv_obj_t * arc = lv_arc_create(lv_scr_act());
lv_arc_set_rotation(arc, 270);
lv_arc_set_bg_angles(arc, 0, 360);
lv_obj_remove_style(arc, NULL, LV_PART_KNOB);   /*Be sure the knob is not displayed*/
lv_obj_clear_flag(arc, LV_OBJ_FLAG_CLICKABLE);  /*To not allow adjusting by click*/
lv_obj_center(arc);

/*
下面创建三个timer,最后创建的timer会被放在timer list的最前面,
lvgl的任务处理器会从timer list从头到尾按顺序遍历检查,执行满足执行条件的timer。
因此,如果三个定时器的周期设置一样的话,那么最后创建的timer会先执行。
*/
lv_timer_t * timer;
/* 创建第一个timer */
timer = lv_timer_create(my_timer1, 500,  NULL);

//lv_timer_set_cb(timer, my_timer1);
//lv_timer_set_period(timer, 100);

// 设置此timer的运行次数,设置后该timer在执行指定次数后会自动删除
// 设置为 -1 就是无限重复,默认值就是 -1
//lv_timer_set_repeat_count(timer, 3);

// 让此timer在下一次调用 lv_timer_handler() 时运行
// 也就是会马上运行,而不是等过了给定的第一个周期过了之后才运行。
// 与它相反的是:lv_timer_reset(timer) 其会重置定时器的周期,
// 这样定时器将在我们设置的毫秒时间段过去后再调用。
lv_timer_ready(timer);

/* 通过另一个接口创建第三个timer */
timer = lv_timer_create_basic();

// 修改此timer的回调函数和周期时间
lv_timer_set_cb(timer, my_timer3);
lv_timer_set_period(timer, 100);

/* 创建一个按钮 */
lv_obj_t * btn = lv_btn_create(lv_scr_act());
lv_obj_add_flag(btn, LV_OBJ_FLAG_CHECKABLE);

// 在事件处理回调函数中我们会进行两个试验:
// 1.点击按钮暂停或继续,上面的第三个timer
lv_obj_add_event_cb(btn, btn_event_handler, LV_EVENT_ALL, timer);
lv_obj_align(btn, LV_ALIGN_CENTER, 0, 0);

static void my_timer3(lv_timer_t * timer)
{
  // 这里不使用NULL判断,如果我们free了arc但是并没有赋值为NULL的时候,
  // 在这里用NULL判断就会出错,通过 lv_obj_check_type 是更好的方法
  if (lv_obj_check_type(arc, &lv_arc_class)) {
    /*每次运行周期都将arc的值+1,
      其中,当arc的值大于所设置的最大值时(默认是100),
      将arc的值设为所设置的最小值(默认是0)
    */
    if (lv_arc_get_value(arc) >= lv_arc_get_max_value(arc)) {
      lv_arc_set_value(arc, lv_arc_get_min_value(arc));
    }
    else {
      lv_arc_set_value(arc, lv_arc_get_value(arc)+1);
    }
  }
}


static void btn_event_handler(lv_event_t * e)
{
  lv_obj_t *btn = lv_event_get_target(e);
  lv_event_code_t code = lv_event_get_code(e);
  lv_timer_t * timer3 = (lv_timer_t *)lv_event_get_user_data(e);

  if(code == LV_EVENT_VALUE_CHANGED) {
    LV_LOG_USER("Toggled");
    // 这里不使用NULL判断,如果我们free了arc但是并没有赋值为NULL的时候,
    // 在这里用NULL判断就会出错,通过 lv_obj_check_type 是更好的方法
    if (lv_obj_check_type(arc, &lv_arc_class)) {
      /*测试1:点击反转第三个timer的状态:暂停、继续*/
      if(lv_obj_has_state(btn, LV_STATE_CHECKED)) {
        LV_LOG_USER("CHECKED!");
        lv_timer_pause(timer3);
      }
      else{
        LV_LOG_USER("UNCHECKED!");
        lv_timer_resume(timer3);
      }
    }
  }
}

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

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

相关文章

帮微软语音助手纠正“阿弥陀佛”“e”字错误发音的技巧

一、前言 微软AI文字转语音助手,现已被大家普便应用。最近在传统文化佛学名词的发音转换应用中,发现了一个致命的错误。那就是“阿弥陀佛”中的“阿”字的“a”发音,被误读为“e”。说起这个重大的错误,佛门大德南怀瑾老师也一再…

排序算法——选择排序

一、介绍: 选择排序就是按照一定的顺序从选取第一个元素索引开始,将其储存在一个变量值中,根据排序规则比较后边每一个元素与这个元素的大小,根据排序规则需要,变量值的索引值进行替换,一轮遍历之后&#x…

【RabbitMQ】docker rabbitmq集群 docker搭建rabbitmq集群

docker rabbitmq集群 docker搭建rabbitmq集群 RabbitMQ提供了两种常用的集群模式 1.普通集群模式 2.镜像集群模式 普通集群模式只能同步主节点上的交换机和队列信息,但对于队列中的消息不做同步,主节点宕机也不能进行切换(故障转移&#xff…

socket can查看详细信息 命令 ip -details -statistics link show can0

ip -details -statistics link show can0 ip -details link show can0 ip -statistics link show can0 也可以像第一行那样结合使用

C语言应用:Linux与Windows的系统化

作为一种广泛应用于软件开发的编程语言,C语言在工业应用领域也发挥着重要的作用。在本文中,我们将深入探索C语言在工业应用中的应用场景和价值,并重点关注它在Linux和Windows系统中的工业化之路。希望本文能为您介绍C语言在工业领域的实际应用…

SpringBoot-黑马程序员-学习笔记(二)

22.读取yaml文件中的属性 3个步骤: 1.写yaml文件 2.在控制类里面定义变量 3.在变量上面用 " Value注解 ${} " 获取yaml文件的属性 代码演示: yaml文件 控制类: 访问网址books后: 读取到了对应了值 23.yaml文件中…

msvcp120.dll文件下载安装,学习msvcp120.dll文件三种重新安装方法

在计算机使用过程中,我们可能会遇到各种意想不到的问题,其中 msvcp120.dll 丢失就是一种比较常见的情况。msvcp120.dll 是微软 Visual Studio 2013 编译的程序所依赖的一个动态链接库文件,它包含了 C标准库的一些功能,如输入输出、…

QT信号与槽机制 和 常用控件介绍

QT信号与槽机制 1、信号(signal): 所谓信号槽 (观察者模式)信号本质是事件。信号展现方式就是函数。当某一个事件发生之后,则发出一个信号(signal). 2、槽(slot): 就是对信号响应的函数,槽就是一个函数。槽函数与普通函数区别槽函数可以与一个信号关联&…

Bootstrap中固定某一个元素不随滚动条滚动

可以利用类sticky-top实现固定某个元素在顶部的效果&#xff0c;示例代码如下&#xff1a; <!DOCTYPE html> <html> <head><meta charset"UTF-8"><title>固定某一个元素不随滚动条滚动</title><meta name"viewport&quo…

vue3 antv 静态登录页面

效果图 <template> <!-- 内容区域 --><div class"main"><div class"from"><!-- 表单 model是antv里边的绑定表单数据 --><a-form :model"formState" ref"formRef"><!-- 切换 --><a-tabs…

06-进程间通信

学习目标 熟练使用pipe进行父子进程间通信熟练使用pipe进行兄弟进程间通信熟练使用fifo进行无血缘关系的进程间通信使用mmap进行有血缘关系的进程间通信使用mmap进行无血缘关系的进程间通信 2 进程间通信相关概念 2.1 什么是进程间通信 Linux环境下&#xff0c;进程地址空间…

FPGA设计时序约束四、多周期约束

目录 一、背景 二、set_multicycle_path a)Targets界面 b)options界面 c)setup与hold关系 三、多周期约束场景 3.1 单时钟域的多周期约束 3.2 多周期路径与时钟相移 3.3 慢时钟到快时钟的多周期约束 3.4 快时钟到慢时钟的多周期约束 四、工程示例 五、参考 一、背景…

广州华锐互动:VR互动教学平台如何赋能职业院校?

随着科技的发展&#xff0c;我们的教育方式也在不断进步。其中&#xff0c;虚拟现实&#xff08;VR&#xff09;技术的出现为我们提供了一种全新的教学方式。特别是在职业学校中&#xff0c;VR互动教学平台已经成为一种重要的教学工具。 VR互动教学平台是一种利用虚拟现实技术创…

游戏软件开发与应用软件开发有什么不同呢?

游戏软件开发和应用软件开发是两种不同类型的软件开发&#xff0c;它们在许多方面都有不同之处。以下是它们之间的一些主要区别&#xff1a; 目标用户群体&#xff1a; 游戏软件开发的主要目标是提供娱乐和休闲体验&#xff0c;通常面向广大的游戏玩家群体。游戏软件的设计和开…

【java基础学习】之DOS命令

#java基础学习 1.常用的DOS命令&#xff1a; dir:列出当前目录下的文件以及文件夹 md: 创建目录 rd:删除目录cd:进入指定目录 cd.. :退回到上级目录 cd\ : 退回到根目录 del:删除文件 exit:退出dos命令行 1.dir:列出当前目录下的文件以及文件夹 2.md: 创建目录 …

Spring实例化源码解析之Custom Events上集(八)

Events使用介绍 在ApplicationContext中&#xff0c;事件处理通过ApplicationEvent类和ApplicationListener接口提供。如果将实现ApplicationListener接口的bean部署到上下文中&#xff0c;每当一个ApplicationEvent被发布到ApplicationContext时&#xff0c;该bean将被通知。…

Android Studio版本升级后的问题 gradle降级、jdk升级

Cannot use TaskAction annotation on method IncrementalTask.taskAction$gradle_core() because interface org.gradle.api.tasks.incremental.IncrementalTaskInputs is not a valid parameter to an action method. 修改下面两处地方分别为7.0.3、7.3.3Android Gradle plu…

Nginx的跨域问题解决

同源策略 浏览器的同源策略&#xff1a;是一种约定&#xff0c;是浏览器最核心也是最基本的安全功能&#xff0c;如果浏览器少了同源策略&#xff0c;则浏览器的正常功能可能都会受到影响。 同源: 协议、域名(IP)、端口相同即为同源 跨域问题 有两台服务器分别为A,B,如果从…

网络安全(自学黑客技术)——黑客学习方法

如果你想自学网络安全&#xff0c;首先你必须了解什么是网络安全&#xff01;&#xff0c;什么是黑客&#xff01;&#xff01; 1.无论网络、Web、移动、桌面、云等哪个领域&#xff0c;都有攻与防两面性&#xff0c;例如 Web 安全技术&#xff0c;既有 Web 渗透2.也有 Web 防…

MySQL运维—从零到放弃

1. 日志 1.1 错误日志 错误日志是 MySQL 中最重要的日志之一&#xff0c;它记录了当 mysqld 启动和停止时&#xff0c;以及服务器在运行过程中发生任何严重错误时的相关信息。当数据库出现任何故障导致无法正常使用时&#xff0c;建议首先查看此日志。 该日志是默认开启的…