前言
今天开始,记录分享一下在做嵌入式开发界面设计过程中的一点心得。
今日分享的是如何创建一个动态的数字式日期、时间、计时器显示控件,这种控件常见于手机的顶部信息栏,如下图。
一、思路
我采用C语言和lvgl库实现,至于lvgl库的版本,尽量采用最新的稳定版本吧(lvgl库较早版本的一些函数现在已经没有了,或者函数名已经改变了)!
这个控件可以用最基本的控件label来实现,label的文本可以设置成日期、时间、时长,那么从系统中获取当地时间,每秒更新到文本就好了,这个每秒的更新可以使用lvgl自己带有的定时器来实现。
以下是实现的代码示例。
二、实现案例
1.time.c
1.在time.c文件中,主要有两个函数,lv_time()函数主要用于创建显示控件,update_time_cb(lv_timer_t *timer)函数是用于更新时间的。
2.而用于创建定时器的函数是lv_timer_create(update_time_cb, 1000, NULL);其中1000是代表1000ms,也就是1秒。
3.需要注意的是 lv_obj_set_style_text_font(label_my_TIM_data, &lv_font_CN_SYHT_N_40, LV_PART_MAIN|LV_STATE_DEFAULT)中的lv_font_CN_SYHT_N_40是自己创建的汉字库,lvgl没有汉字库,如何在lvgl库中创建汉字库等以后有时间再分享。
#include "lv_test_main.h"
lv_obj_t* label_date; //日期label控件
lv_obj_t* label_time; //时间label控件
lv_obj_t* label_duration; //时长label控件
/**
*时间、日期、时长控件显示函数
*/
void lv_time()
{
lv_obj_t* time_bg = lv_obj_create(NULL);//创建背景界面
lv_obj_set_style_bg_color(time_bg,lv_color_make(0,0,0),0);//设置背景颜色为黑色
lv_obj_set_scrollbar_mode(time_bg, LV_SCROLLBAR_MODE_OFF);//关闭界面的滚动条
lv_scr_load(time_bg);
label_time = lv_label_create(time_bg);//时间控件
lv_obj_set_size(label_time, 200, 36);
lv_label_set_text(label_time, "00:00:00");
lv_obj_align(label_time,LV_ALIGN_CENTER,120,-30);
lv_obj_set_style_text_color(label_time, lv_color_make(255,255,255), 0);
lv_obj_set_style_text_font(label_time, &lv_font_montserrat_36, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_text_align(label_time, LV_TEXT_ALIGN_LEFT, LV_PART_MAIN|LV_STATE_DEFAULT);
label_date = lv_label_create(time_bg);//日期控件
lv_obj_set_size(label_date, 250, 36);
lv_label_set_text(label_date, "2023/01/01");
lv_obj_align(label_date,LV_ALIGN_CENTER,-80,-30);
lv_obj_set_style_text_color(label_date, lv_color_make(255,255,255), 0);
lv_obj_set_style_text_font(label_date, &lv_font_montserrat_36, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_text_align(label_date, LV_TEXT_ALIGN_LEFT, LV_PART_MAIN|LV_STATE_DEFAULT);
label_duration = lv_label_create(time_bg);//时长控件
lv_label_set_text_fmt(label_duration, "时长: %d min", 0);//汉字“时长”两字需要自己创建汉字库才能实现
lv_obj_set_style_text_color(label_duration, lv_color_make(255,255,255), 0);
lv_obj_set_style_text_font(label_duration, &lv_font_CN_SYHT_N_40, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_align(label_duration, LV_ALIGN_CENTER, 0, 30);
lv_timer_create(update_time_cb, 1000, NULL);//创建一个定时器,每秒更新一次日期、时间、时长
}
/**
*时间和日期更新回调函数
*/
void update_time_cb(lv_timer_t *timer) {
time_t now;
struct tm tm;
// 获取当前本地时间
now = time(NULL);
localtime_r(&now, &tm);
static time_t start_time = 0;//初始时长为0
if (start_time == 0) {start_time = now;}
char time_str[9]; // 存放格式化后的时间字符串,HH:MM:SS
char date_str[20]; // 存放格式化后的日期字符串,YYYY-MM-DD
int total_minute = (now - start_time) / 60; // 计算累计时长(分钟)
// 将时间格式化为字符串,精确到秒
snprintf(time_str, sizeof(time_str), "%02d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec);
// 将日期格式化为字符串,精确到日
snprintf(date_str, sizeof(date_str), "%04d/%02d/%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
lv_label_set_text(label_time, time_str); // 更新时间标签的文本
lv_label_set_text(label_date, date_str); // 更新日期标签的文本
lv_label_set_text_fmt(label_duration, "时长: %d min", total_minute);//更新时长标签的文本
}
2.lv_test_main.h
1.需要注意的是一定要引入time.h,系统时间的获取要依靠它。
2.LV_FONT_DECLARE(lv_font_CN_SYHT_N_40)//思源黑体40号 是我创建的基于思源黑体的汉字库,其他几个是其他字号的汉字库,小伙伴们要是用不到可以把这段删除,但是.c文件中的lv_font_CN_SYHT_N_40要换回成vgl自己的字体库,如lv_font_montserrat_36。
#include "../lv_examples/lv_demo.h"
#include <time.h>
#include <errno.h>
#include <fcntl.h>
#include <dirent.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "math.h"
#include "stdio.h"
#include "stdlib.h"
LV_FONT_DECLARE(lv_font_CN_SYHT_N_28)//思源黑体28号
LV_FONT_DECLARE(lv_font_CN_SYHT_N_32)//思源黑体32号
LV_FONT_DECLARE(lv_font_CN_SYHT_N_40)//思源黑体40号
LV_FONT_DECLARE(lv_font_CN_SYHT_N_48)//思源黑体48号
void lv_time(void);
void update_time_cb(lv_timer_t *timer);
2.main函数
1.在main函数中,根据lvgl给的示例,lvgl的运行要依靠于while的循环。
int main(int argc, char **argv)
{
(void)argc; /*Unused*/
(void)argv; /*Unused*/
/*Initialize LVGL*/
lv_init();
/*Initialize the HAL (display, input devices, tick) for LVGL*/
hal_init();
/*要运行的demo*/
lv_time();
while(1) {
lv_timer_handler();
usleep(5 * 1000);
}
return 0;
}
三、效果展示
总结
以上就是今天要分享的动态数字式日期、时间、时长控件的创建,如有疑问,欢迎评论区讨论。