Qt实现数字滚动动画效果

自己开发了一个股票智能分析软件,功能很强大,需要的点击下面的链接获取:

https://www.cnblogs.com/bclshuai/p/11380657.html

1.1  Qt实现数字滚动动画效果

1.1.1         应用场景说明

如下图所示,需要显示人脸检测的数量,变动画的方式实现个位数字滚动,个位由9变成0时,十位也要滚动,实现进位。当个位十位都是9时,数字不在增加,而是显示加号+。

 

 

 

 

  

1.1.2         实现方法

实现方案,个位十位都有上下两个label显示数字。通过QPropertyAnimation属性动画控制两个label位置同时向上。动画结束后,再将两个label还原到原始位置。在还原位置之前,先前上面的labelnum值设置为下面labelnum1的值,下面labelnum1的值设置为+1后的值,避免出现数字闪现变小的问题。

 

头文件实现

 

 

#ifndef NUMSHOWWIDGET_H

#define NUMSHOWWIDGET_H

#include <QPropertyAnimation>

#include<QParallelAnimationGroup>

#include <QSequentialAnimationGroup>

#include <QWidget>

#include"ui_NumShowWidget.h"

#include<QMutex>

#include<QWaitCondition>

#include<QTimer>

class NumShowWidget : public QWidget

{

    Q_OBJECT

 

public:

    NumShowWidget();

    ~NumShowWidget();

    void initNum();//个位十位上下初始化0,1值

    /*

    设置为某个值,会根据数字增量的大小增加数字值,根据time求出平均动画时间步长。增量大时速度快,增量小时速度慢

    */

    void setNum(int num,int time);

    void addNum(int num, int time);

    public slots:

    void SlotTimeAddNum();

    int getNum();

    void pushNum(int num);

private:

    Ui::NumShowWidget ui;

    int m_tenwei = 0;//十位

    int m_gewei = 0;//个位

    QLabel* m_tenCurrent = NULL;//十位当前label

    QLabel* m_tenDown=NULL;//十位下面的label

    QLabel* m_geCurrent = NULL;//个位当前label

    QLabel* m_geDown = NULL;//个位下面的label

    int m_count = 0;//动画执行的次数,增量为10,则执行十次上滚动画

    int m_num=0;//保存当前显示的数字。

    QParallelAnimationGroup* tenAnimation;

    QMutex m_mutex;

    QWaitCondition m_FinishAnimation;

    QTimer m_checktime;

    QMutex m_addNumMutex;

    QVector<int> m_vectNum;

    bool m_bFinishAni=true;//避免第一次动画未执行结束,第二次动画就开始,会错乱,所加上一个判断条件。

    QPropertyAnimation * tenCurrent =NULL;

    QPropertyAnimation * tenDown = NULL;

};

#endif // NUMSHOWWIDGET_H

源文件实现

#include "NumShowWidget.h"

#include"hlog1.h"

#include<QFontDatabase>

NumShowWidget::NumShowWidget()

{

    ui.setupUi(this);

    setWindowModality(Qt::NonModal);

    setWindowFlags(Qt::FramelessWindowHint);

    this->resize(32, 32);

    m_tenCurrent = ui.labelten;

    m_tenDown = ui.labelten1;

    m_geCurrent = ui.labelnum;

    m_geDown = ui.labelnum1;

    m_tenCurrent->setText("0");

    m_tenDown->setText("1");

    m_geCurrent->setText("0");

    m_geDown->setText("1");

    ui.labelplus->hide();

    tenAnimation = new QParallelAnimationGroup(this);

    tenCurrent = new QPropertyAnimation(m_tenCurrent, "geometry");

    tenCurrent->setDuration(100);

    tenCurrent->setStartValue(QRect(4, 0, 12, 32));

    tenCurrent->setEndValue(QRect(4, -32, 12, 32));

    tenAnimation->addAnimation(tenCurrent);

    tenDown = new QPropertyAnimation(m_tenDown, "geometry");

    tenDown->setDuration(100);

    tenDown->setStartValue(QRect(4, 32, 12, 32));

    tenDown->setEndValue(QRect(4, 0, 12, 32));

    tenAnimation->addAnimation(tenDown);

    connect(tenAnimation, &QAbstractAnimation::finished, this, [=]() {

        m_tenCurrent->setText(QString::number(m_tenwei++));

        m_tenCurrent->setGeometry(4, 0, 12, 32);

        m_tenCurrent->raise();

        m_tenDown->setGeometry(4, 32, 12, 32);

        m_tenDown->setText(QString::number((m_tenwei + 1)));

    });

    m_checktime.setInterval(1000);

    connect(&m_checktime, &QTimer::timeout, this, &NumShowWidget::SlotTimeAddNum);

    m_checktime.start();

}

 

NumShowWidget::~NumShowWidget()

{

    if (tenAnimation != NULL)

    {

        delete tenAnimation;

        tenAnimation = NULL;

    }

}

 

void NumShowWidget::initNum()

{

    m_tenwei = 1;

    m_gewei = 1;

    m_num = 0;

    m_tenCurrent->setText("0");

    m_tenCurrent->setGeometry(QRect(4, 0, 12, 32));

    m_tenDown->setText("1");

    m_tenDown->setGeometry(QRect(4, 32, 12, 32));

    m_geCurrent->setText("0");

    m_geDown->setText("1");

    m_geCurrent->setGeometry(QRect(15, 0, 12, 32));

    m_geDown->setGeometry(QRect(15, 32, 12, 32));

    ui.labelplus->hide();

    m_vectNum.clear();

    m_bFinishAni = true;

   

}

 

void NumShowWidget::setNum(int num, int time)

{

    if (ui.labelplus->isVisible())

    {

        return;

    }

    m_num = ui.labelten->text().toInt()*10+ui.labelnum->text().toInt();

    if (num <= m_num)//值没有变

    {

        m_mutex.lock();

        m_bFinishAni = true;

        m_mutex.unlock();

        return;

    }

    addNum(num - m_num, time);

}

 

void NumShowWidget::addNum(int num, int time)

{

   

    if (num <= 0)

    {

        return;

    }

    LOG_INFO("NUCOUNT LOCK");

    int steptime = time / num;//动画时间步长

    tenCurrent->setDuration(steptime);

    tenDown->setDuration(steptime);

    m_count = num;

    QParallelAnimationGroup* paraAnimation = new QParallelAnimationGroup(this);

    QPropertyAnimation * geCurrent = new QPropertyAnimation(m_geCurrent, "geometry");

    geCurrent->setDuration(steptime);

    geCurrent->setStartValue(QRect(15, 0, 12, 32));

    geCurrent->setEndValue(QRect(15, -32, 12, 32));

    paraAnimation->addAnimation(geCurrent);

    QPropertyAnimation *geDown = new QPropertyAnimation(m_geDown, "geometry");

    geDown->setDuration(steptime);

    geDown->setStartValue(QRect(15, 32, 12, 32));

    geDown->setEndValue(QRect(15, 0, 12, 32));

    paraAnimation->addAnimation(geDown);

    paraAnimation->start();

    connect(paraAnimation, &QAbstractAnimation::finished, this, [=]() {

        m_count--;

        m_geCurrent->setText(QString::number(m_gewei++));

        m_geCurrent->setGeometry(15, 0, 12, 32);

        m_geCurrent->raise();

        m_geDown->setGeometry(15, 32, 12, 32);

        if (m_gewei >= 10)

        {

             if (m_tenwei < 10)

             {

                 tenAnimation->start();

             }

             else

             {

                 ui.labelplus->show();

                 m_mutex.lock();

                 m_bFinishAni = true;

                 m_mutex.unlock();

                 delete paraAnimation;

                 LOG_INFO("NUCOUNT ULOCK");

                 return;

            }

             m_gewei = 0;

        }

        m_geDown->setText(QString::number((m_gewei) % 10));

        if (m_count > 0)

        {

             paraAnimation->start();

        }

        else

        {

             m_mutex.lock();

             m_bFinishAni = true;

             m_mutex.unlock();

             delete paraAnimation;

             LOG_INFO("NUCOUNT ULOCK");

            

        }

    })

}

void NumShowWidget::SlotTimeAddNum()

{

    if (m_bFinishAni)

    {

        int num = getNum();

        if (num > 0)

        {  

             m_mutex.lock();

             m_bFinishAni = false;

             m_mutex.unlock();

             setNum(num, 1000);

            

        }

    }

}

int NumShowWidget::getNum()

{

    m_addNumMutex.lock();

    if (m_vectNum.size() > 0)

    {

        int num = m_vectNum.front();

        m_vectNum.pop_front();

        m_addNumMutex.unlock();

        return num;

    }

    else

    {

        m_addNumMutex.unlock();

        return -1;

    }

   

}

void NumShowWidget::pushNum(int num)

{

    m_addNumMutex.lock();

    m_vectNum.push_back(num);

    m_addNumMutex.unlock();

}

posted @ 2020-12-08 19:00  一字千金  阅读(1676)  评论(0编辑  收藏  举报