Qt/C++控件实例 QWidget联合动画实现卷轴效果

显示特点

  1. 动态翻页效果:数字在更新时,会有一个从前一数字向下一数字过渡的翻页效果。这种过渡动画使得数字变化过程更加平滑和自然,避免了突然的跳变。

  2. 高对比度显示:每个数字的背景框颜色为红色,数字颜色为白色,这种高对比度设计确保了数字在不同环境下的可读性。

  3. 多位数字同步翻转:控件支持同时翻转多位数字,适用于五位数的显示。每位数字都在相同的时间段内平滑地过渡到新的数值,营造整体的翻页效果。

这种翻页效果不仅美观,而且实用,适合需要频繁更新的数值显示场合,通过视觉动画增强用户体验。

#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)); // 在当前数字的位置绘制数字
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

极客晨风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值