【前言】
TouchGFX有成熟的时钟组件,这篇介绍如果快速的制作一个时钟。
【模拟时钟组件介绍】
模拟时钟是一个控件,能够显示一个传统的模拟时钟,而不是通过文本显示时间的数字时钟。 该时钟使用背景图像作为钟面。 时针、分针和秒针都使用一幅图像,并围绕一个可配置的中心旋转。
模拟时钟位于TouchGFX Designer中的Miscellaneous控件组中。
模拟时钟位于TouchGFX Designer中的Miscellaneous控件组中。
TouchGFX Designer中模拟时钟的属性。
属性组属性说明
| 名称 | 控件的名称。 名称是TouchGFX Designer和代码中使用的唯一标识符。 |
| 位置 | X 和Y 指定控件左上角相对于其父的位置。 W 和 H 指定控件的宽度和高度。 模拟时钟的大小是从关联图像的大小获取的,其大小无法更改(除非更改图像)。 锁定指定控件是否应锁定为其当前的X、Y、W和H。 如果锁定控件,还会禁止通过屏幕与控件进行交互。 可见 指定控件的可见性。 如果将控件标记为不可见,还会禁止通过屏幕与控件进行交互。 |
| 样式 | 样式 指定控件的预定义设置,用于将所选属性设为预定义的值。 这些样式包含可免费使用的图像。 |
| 外观 | 图像 指定用作背景的图像。 X轴旋转中心 和 Y轴旋转中心 指定时钟指针应该绕着旋转的点 |
| 时间 | 使用Am/Pm指定时间格式是12小时制还是24小时制。 初始时间指定时钟显示的初始时间。 |
| 时钟指针 | 时钟指针 指定模拟时钟应该显示哪个时钟指针(秒针、分针和时针)、 以及指针的顺序。 每根时钟指针都可以通过设置旋转位置X和旋转位置Y来设置一个指针图像和各自的旋转点。 分针和时针都可选择使用扫描式指针动作,方法是设置扫描式动作 |
| 动画 | 动画式时钟指针动作指定是否启用时钟指针的动画效果。 持续时间指定动画效果的持续时间。 缓动 和 缓动选项 指定使用的缓动方程。 |
| Mixin | 可拖动 指定在运行时控件是否可拖动。 ClickListener 指定控件被点击时是否会调用回调函数。 MoveAnimator 指定控件是否可绘制 X 和 Y 值变化的动画。 |
【GUI制作】
根据官方教程,向屏幕添加一个模拟时钟组件:

也可以根据自己的需要,更换不时大小、样式的组件:

当然也还可以使用自定义的表盘图像、时、分、秒等来高度定制自己的摸拟时钟。
时钟组件放置好后,他是不会自己动的,需要用户定时修改组件的时、分、秒来实现实时显示。时钟设置的功能函数为:
【实现RTC实时时间】
实现RTC实时时间,可以通过STM32CubeMX来配置,这次介绍不是重点,所以我直接引用原来自己已经配置好的RTC函数来直接实现。即从其他已经配置好的工程中复制rtc.c/h到工程之中。
然后在model.c的tick函数来实现每秒钟获取一次时间。其代码如下:
#include <gui/model/Model.hpp>
#include <gui/model/ModelListener.hpp>
#include <cstdint>
#ifndef SIMULATOR
#include "main.h"
#include "rtc.h"
extern RTC_HandleTypeDef hrtc;
RTC_DateTypeDef gSystemDate; //获取日期结构体
RTC_TimeTypeDef gSystemTime; //获取时间结构体
#endif
Model::Model() : modelListener(0),hour(0), minute(0),second(0)
{
}
void Model::tick()
{
static int tick_counter;
if(tick_counter++ == 60)
{
tick_counter = 0;
get_rtc_Time();
}
}
#ifndef SIMULATOR
void Model::get_rtc_Time()
{
HAL_RTC_GetTime(&hrtc, &gSystemTime, RTC_FORMAT_BIN);
HAL_RTC_GetDate(&hrtc, &gSystemDate, RTC_FORMAT_BIN);
hour = gSystemTime.Hours;
minute = gSystemTime.Minutes;
second = gSystemTime.Seconds;
}
#endif根据M-P-V模型架构,在ModelLister.hpp中添加代码如下,实现hour、minuter、second转递。
/* 添加时间获取函数 */
/* 2024/9/15 */
int16_t getHour()
{
return model->getHour();
}
int16_t getMinute()
{
return model->getMinute();
}
int16_t getSecond()
{
return model->getSecond();
}
/* 添加时间获取函数结束 */在view.cpp中添加handlerEvent函数,每60个tick修改一次时间,实现时钟的实时刷新:
void Screen1View::handleTickEvent() {
static int16_t tick;
tick++;
if(tick%60==0)
{
tick = 0;
hour = presenter->getHour();
minute = presenter->getMinute();
second = presenter->getSecond();
analogClock.setTime24Hour(hour, minute, second);
}
}【实验效果】

我要赚赏金
