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();

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM