自己開發了一個股票智能分析軟件,功能很強大,需要的點擊下面的鏈接獲取:
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();
}
