【前言】
TouchGFX有成熟的时钟组件,这篇介绍如果快速的制作一个时钟。
【模拟时钟组件介绍】
模拟时钟是一个控件,能够显示一个传统的模拟时钟,而不是通过文本显示时间的数字时钟。 该时钟使用背景图像作为钟面。 时针、分针和秒针都使用一幅图像,并围绕一个可配置的中心旋转。
模拟时钟位于TouchGFX Designer中的Miscellaneous控件组中。
控件组
模拟时钟位于TouchGFX Designer中的Miscellaneous控件组中。
TouchGFX Designer中的模拟时钟
属性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制作】
根据官方教程,向屏幕添加一个模拟时钟组件:
也可以根据自己的需要,更换不时大小、样式的组件:
当然也还可以使用自定义的表盘图像、时、分、秒等来高度定制自己的摸拟时钟。
时钟组件放置好后,他是不会自己动的,需要用户定时修改组件的时、分、秒来实现实时显示。时钟设置的功能函数为:
analogClock.setTime24Hour(hour, minute, second);
【实现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); } }
【实验效果】