显示特点
-
动态翻页效果:数字在更新时,会有一个从前一数字向下一数字过渡的翻页效果。这种过渡动画使得数字变化过程更加平滑和自然,避免了突然的跳变。
-
高对比度显示:每个数字的背景框颜色为红色,数字颜色为白色,这种高对比度设计确保了数字在不同环境下的可读性。
-
多位数字同步翻转:控件支持同时翻转多位数字,适用于五位数的显示。每位数字都在相同的时间段内平滑地过渡到新的数值,营造整体的翻页效果。
这种翻页效果不仅美观,而且实用,适合需要频繁更新的数值显示场合,通过视觉动画增强用户体验。
#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.0animation->setEndValue(1.0); // 动画结束值为 1.0connect(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); // 设置字体大小为 32font.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)); // 在当前数字的位置绘制数字}
}