显示特点
-
动态翻页效果:数字在更新时,会有一个从前一数字向下一数字过渡的翻页效果。这种过渡动画使得数字变化过程更加平滑和自然,避免了突然的跳变。
-
高对比度显示:每个数字的背景框颜色为红色,数字颜色为白色,这种高对比度设计确保了数字在不同环境下的可读性。
-
多位数字同步翻转:控件支持同时翻转多位数字,适用于五位数的显示。每位数字都在相同的时间段内平滑地过渡到新的数值,营造整体的翻页效果。
这种翻页效果不仅美观,而且实用,适合需要频繁更新的数值显示场合,通过视觉动画增强用户体验。
#include "flipcounter.h"
#include <QPainter>
// 构造函数,初始化 FlipCounter 对象
FlipCounter::FlipCounter(QWidget *parent)
: QWidget(parent), previousValue(0), currentValue(0), m_progress(0.0) {
setFixedSize(260, 100); // 设置控件的固定大小为 260x100 像素
// 初始化动画
animation = new QPropertyAnimation(this, "progress"); // 创建动画对象,目标属性为 "progress"
animation->setDuration(500); // 设置动画持续时间为 500 毫秒
animation->setStartValue(0.0); // 动画开始值为 0.0
animation->setEndValue(1.0); // 动画结束值为 1.0
connect(animation, &QPropertyAnimation::valueChanged, this, QOverload<>::of(&FlipCounter::update)); // 连接动画的值变化信号到 update 槽函数,用于触发重绘
}
// 设置数字并开始动画
void FlipCounter::setNumbers(int previous, int current) {
previousValue = previous; // 设置前一个数值
currentValue = current; // 设置当前数值
m_progress = 0.0; // 重置进度为 0.0
// 开始翻页动画
animation->start(); // 启动动画
}
// 获取当前进度
double FlipCounter::progress() const {
return m_progress; // 返回当前进度
}
// 设置进度并更新绘制
void FlipCounter::setProgress(double value) {
m_progress = value; // 设置新的进度值
update(); // 触发重新绘制
}
// 绘制事件
void FlipCounter::paintEvent(QPaintEvent *event) {
QPainter painter(this); // 创建 QPainter 对象
painter.setRenderHint(QPainter::Antialiasing); // 开启抗锯齿
painter.setRenderHint(QPainter::TextAntialiasing); // 开启文字抗锯齿
// 绘制整体背景
painter.setBrush(QColor(22, 53, 81)); // 设置背景颜色为深蓝色
painter.drawRect(0, 0, width(), height()); // 绘制整个控件的背景矩形
// 设置字体
QFont font = painter.font();
font.setPointSize(32); // 设置字体大小为 32
font.setBold(true); // 设置字体加粗
painter.setFont(font); // 应用字体设置
// 设置绘制参数
int digitSpacing = 10; // 数字之间的水平间隔
int charPadding = 4; // 缩小背景框与数字的间隔
int charWidth = (width() - (5 - 1) * digitSpacing) / 5; // 计算每个字符的宽度
int charHeight = height() - 2 * charPadding; // 计算每个字符的高度
// 将前一个数值和当前数值转换为 5 位的字符串,不足位用 0 填充
QString prevText = QString("%1").arg(previousValue, 5, 10, QChar('0'));
QString currText = QString("%1").arg(currentValue, 5, 10, QChar('0'));
// 循环绘制每一位数字
for (int i = 0; i < 5; ++i) {
int prevDigit = prevText.mid(i, 1).toInt(); // 获取前一个数值的第 i 位数字
int currDigit = currText.mid(i, 1).toInt(); // 获取当前数值的第 i 位数字
QRect baseRect(i * (charWidth + digitSpacing), charPadding, charWidth, charHeight); // 计算当前位数字的基础矩形区域
int offset = m_progress * charHeight; // 根据进度计算垂直偏移量
QRect prevRect = baseRect.translated(0, -offset); // 计算前一个数字的位置,向上偏移
QRect currRect = baseRect.translated(0, charHeight - offset); // 计算当前数字的位置,向下偏移
// 绘制前一个数字及其背景框
QRect prevBackgroundRect = prevRect.adjusted(-charPadding, -charPadding, charPadding, charPadding); // 计算前一个数字背景框的矩形区域
painter.setBrush(QColor(200, 42, 65)); // 设置背景颜色为红色
painter.setPen(Qt::NoPen); // 不绘制边框
painter.drawRect(prevBackgroundRect); // 绘制前一个数字的背景框
painter.setPen(Qt::white); // 设置画笔颜色为白色,用于绘制数字
painter.drawText(prevRect, Qt::AlignCenter, QString::number(prevDigit)); // 在前一个数字的位置绘制数字
// 绘制当前数字及其背景框
QRect currBackgroundRect = currRect.adjusted(-charPadding, -charPadding, charPadding, charPadding); // 计算当前数字背景框的矩形区域
painter.setBrush(QColor(200, 42, 65)); // 设置背景颜色为红色
painter.setPen(Qt::NoPen); // 不绘制边框
painter.drawRect(currBackgroundRect); // 绘制当前数字的背景框
painter.setPen(Qt::white); // 设置画笔颜色为白色,用于绘制数字
painter.drawText(currRect, Qt::AlignCenter, QString::number(currDigit)); // 在当前数字的位置绘制数字
}
}