Qt動畫使用總結


自己開發了一個股票智能分析軟件,功能很強大,需要的點擊下面的鏈接獲取:

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

Qt動畫

目錄

1      簡介

1.1     Qt動畫類介紹

2      基礎動畫實現

2.1     Qt控件大小縮放和位置變化

2.2     透明度控制隱藏和顯示

2.3     並行動畫

2.4     串行動畫

2.5     動畫執行方向設置

2.6     動畫循環次數設置

2.7     動畫執行結束的操作

3      Qt的高級動畫應用

3.1     Qt自定義動畫屬性實現背景色透明度動畫

3.2     Tab條選擇跟隨移動

3.2.1     應用場景說明

3.2.2     實現方法

3.3     Qt實現數字滾動動畫效果

3.3.1     應用場景說明

3.3.2     實現方法

4      附錄

4.1     Qt動畫QEasingCurve的速度曲線

 

 

1       簡介

1.1  Qt動畫類介紹

 

 

 

類名

功能介紹

QAbstractAnimation

動畫基類

提供基本的動畫屬性和接口,它有兩個子類QVariantAnimation 和QAnimationGroup。QAbstractAnimation是其他所有類的父類。它提供了基礎的屬性,適用於所有的本框架下的動畫。

QPropertyAnimation

實際的動畫類

,實現了一個Qt動畫屬性,比如對控件的大小縮放、位置移動、透明度變化的動畫效果實現。修改的屬性一定是類具有的屬性,類中要有屬性定義Q_PROPERTY(QRect geometry READ geometry WRITE setGeometry),否則要聲明屬性,並實踐READ和WRITE方法。

QParallelAnimationGroup

並行動畫類

將多個屬性動畫QPropertyAnimation添加到一個QParallelAnimationGroup,實現並行執行動畫。

QSequentialAnimationGroup

串行動畫類

QSequentialAnimationGroup,將多個QPropertyAnimation串聯在一起實現,按照添加順序先后執行動畫。

QPauseAnimation停頓類

在串行動畫中,添加一個暫停的動畫,可以實現延時效果。

QEasingCurve速度曲線類

Qt動畫運動的速度曲線,枚舉了45種,詳見附錄。

 

2       基礎動畫實現

2.1  Qt控件大小縮放和位置變化

通過修改geometry屬性實現坐標和大小的動畫效果。通過創建QPropertyAnimation對象,關聯widget控件ui.widgetProcess,設置屬性geometry。QRect(x,y,width,hight),通過設置x,y改變位置,通過設置width和hight來改變大小。如下圖所示,相似度widget向上移動同時隱藏。進度顯示widget窗口從下往上移動,從隱藏到顯示。

 

 

 

 

 

 

 

 

 

下面是坐標控制

QPropertyAnimation * pWidgetProcessUp = new QPropertyAnimation(ui.widgetProcess, "geometry");

        pWidgetProcessUp->setDuration(300);//設置動畫執行時間,單位毫秒

        pWidgetProcessUp->setStartValue(QRect(140, 688, 534, 48));//初始值

        pWidgetProcessUp->setEndValue(QRect(140, 668, 534, 48));//結束值

        pWidgetProcessUp->setEasingCurve(QEasingCurve::Linear);設置速度曲線

pWidgetProcessUp->start(QAbstractAnimation::DeleteWhenStopped);//執行動畫,結束后刪除對象

2.2  透明度控制隱藏和顯示

因為qt控件沒有透明度屬性opacity,所以需要通過QGraphicsOpacityEffect實現控件繪圖效果實現透明度改變

頭文件定義

QGraphicsOpacityEffect* m_widgetProcessOpacity;

構造函數中定義

m_widgetProcessOpacity=new  QGraphicsOpacityEffect (ui.widgetProcess);//創建QGraphicsOpacityEffect對象關聯控件ui.widgetProcess

    m_widgetProcessOpacity->setOpacity(0);//設置透明度為0,隱藏控件

    ui.widgetProcess->setGraphicsEffect(m_widgetProcessOpacity);//控件添加繪圖效果

函數中使用

QPropertyAnimation* pWidgetProcessOpacity = new QPropertyAnimation(m_widgetProcessOpacity, "opacity", ui.widgetProcess);

        pWidgetProcessOpacity->setDuration(300);

        pWidgetProcessOpacity->setStartValue(0);

        pWidgetProcessOpacity->setEndValue(1);

        pWidgetProcessOpacity->setEasingCurve(QEasingCurve::Linear);

pWidgetProcessOpacity->start(QAbstractAnimation::DeleteWhenStopped);//執行動畫,結束后刪除對象。

 

2.3  並行動畫

實際使用中需要將多個控件的屬性動畫一起執行,實現豐富的動畫效果,將多個屬性動畫QPropertyAnimation添加到一個QParallelAnimationGroup,實現並行執行動畫。例如將上面的兩個動畫合並,同時改變控件ui.widgetProcess的位置、大小、透明度。

QParallelAnimationGroup* pParaTwo = new QParallelAnimationGroup(this);

pParaTwo->addAnimation(pWidgetProcessUp);

pParaTwo->addAnimation(pWidgetProcessOpacity);

pParaTwo-> start(QAbstractAnimation::DeleteWhenStopped);//執行后刪除

2.4  串行動畫

可以實現同一個控件的不同屬性變化串行,也可以實現多個控件的串行動畫。還可以在動畫之間添加暫停動畫QPauseAnimation,實現延時的效果。

QSequentialAnimationGroup* pSequenAno = new QSequentialAnimationGroup(this);

//透明度從0變為1,顯示出來;

pSequenAno->addAnimation(pWidgetProcessOpacity);

//暫停一秒

QPauseAnimation *pPauseAnimation = new QPauseAnimation(this);

pPauseAnimation->setDuration(1000);

//再向上移動

pSequenAno->addAnimation(pWidgetProcessUp);

pSequenAno->start(QAbstractAnimation::DeleteWhenStopped);

2.5  動畫執行方向設置

Qt動畫執行可以設置執行方向,為正向Forward和方向Backward,例如透明度變化正向是初始值setStartValue(0);結束值設置setEndValue(1);控件從隱藏到顯示。可以設置動畫執行方向為反向,pWidgetProcessOpacity –>s etDirection(QAbstractAnimation::Backward),這樣就可以執行顯示到隱藏的動畫。動畫的執行一般是雙向的,可以通過方向控制,避免創建反向的動畫流程。

enum Direction {

        Forward,

        Backward

};

2.6  動畫循環次數設置

有時需要執行動畫多次,或者無限循環下去,可以設置動畫循環次數。設置為-1時表示無限循環。

void setLoopCount(int loopCount);

2.7  動畫執行結束的操作

動畫結束之后執行一些清理工作,或者屬性設置工作,可以連接QAbstractAnimation::finished信號,動畫結束之后再執行一些操作。也可以將動畫對象的清理放入槽函數中。這樣就不能start(QAbstractAnimation::DeleteWhenStopped);

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

             ui.pushButtonAddVideo->setDisabled(true);

             ui.pushButtonDelVideo->setDisabled(true);

             ui.pushButtonAddPic->setDisabled(true);

             ui.pushButtonDelPic->setDisabled(true);

             PausePlayVedio(1, 0);//先創建索引,准確時間定位

        });

 

3       Qt的高級動畫應用

3.1  Qt自定義動畫屬性實現背景色透明度動畫

自定義一個背景色透明度的屬性,在定義get和set方法,在set方法中去通過setstytlesheet去設置背景色的透明度。

Q_PROPERTY(int alpha READ alpha WRITE setAlpha)

動畫執行的過程中,通過set方法動態的設置背景色透明度。可以通過setKeyValueAt函數設置關鍵點的取值,step取值范圍是0~1,可以設置幾個值。動畫執行過程中就會在這個幾個值之間切換。

void setKeyValueAt(qreal step, const QVariant &value);

 

頭文件實現

#ifndef MAIN_WINDOW_H

#define MAIN_WINDOW_H

 

        ...

 

             class MainWindow : public CustomWindow

        {

             Q_OBJECT

                 Q_PROPERTY(int alpha READ alpha WRITE setAlpha)

 

        public:

             explicit MainWindow(QWidget *parent = 0);

             ~MainWindow();

 

        private:

             int alpha() const;

             void setAlpha(const int alpha);

 

        private:

             int m_nAlpha;

             QLabel *m_pLabel;

        };

 

#endif // MAIN_WINDOW_H

源文件實現

#include "main_window.h"

 

        MainWindow::MainWindow(QWidget *parent)

             : CustomWindow(parent)

        {

             ...

 

                 QPushButton *pStartButton = new QPushButton(this);

             pStartButton->setText(QString::fromLocal8Bit("開始動畫"));

 

             m_pLabel = new QLabel(this);

             m_pLabel->setText(QString::fromLocal8Bit("一去丶二三里"));

             m_pLabel->setAlignment(Qt::AlignCenter);

             m_pLabel->setStyleSheet("color: rgb(0, 160, 230);");

 

             QPropertyAnimation *pAnimation = new QPropertyAnimation();

             pAnimation->setTargetObject(this);

             pAnimation->setPropertyName("alpha");

             pAnimation->setDuration(1000);

             pAnimation->setKeyValueAt(0, 255);

             pAnimation->setKeyValueAt(0.5, 100);

             pAnimation->setKeyValueAt(1, 255);

             pAnimation->setLoopCount(-1);  //永遠運行,直到stop

             connect(pStartButton, SIGNAL(clicked(bool)), pAnimation, SLOT(start()));

 

             ...

        }

 

        int MainWindow::alpha() const

        {

             return m_nAlpha;

        }

 

        void MainWindow::setAlpha(const int alpha)

        {

             m_nAlpha = alpha;

             QString strQSS = QString("color: rgb(0, 160, 230); ").arg(m_nAlpha);

             m_pLabel->setStyleSheet(strQSS);

        }

注意事項:

(1)需要用QVariantAnimation檢測你自定義的QVariant類型是否支持。

(2)聲明屬性的類必須是一個QObject,必須為屬性提供一個setter(這樣,QPropertyAnimation才可以設置屬性的值)。

3.2  Tab條選擇跟隨移動

3.2.1         應用場景說明

如下圖所示,初始狀態,tab條在第一張圖片下方,當鼠標放入第三張圖片上時,觸發了hover信號,tab條則會延長到第三張圖片。如果單擊第三張圖片,tab條則會切換到第三張圖片,如果沒有單擊則失去hover時,tab條還原到第一張圖片。從而實現選擇切換的動畫顯示。

 

3.2.2         實現方法

(1)   現在圖片顯示的自定義widget類中重寫鼠標進入、離開、單擊的函數,自定義三種信號,鼠標進入、離開、點擊時觸發信號傳遞到外面。

signals:

    void signalPicClicked();//鼠標單擊信號

    void  signalEnterPicWidget();

    void  signalLeavePicWidget();

protected:

    void enterEvent(QEvent *e);                      //進入QWidget瞬間事件

    void leaveEvent(QEvent *e);                      //離開QWidget瞬間事件

    void mousePressEvent(QMouseEvent* e);

void enterEvent(QEvent *e);                      //進入QWidget瞬間事件

void leaveEvent(QEvent *e);                      //離開QWidget瞬間事件

(2)   將三種信號進行連接

 

for (int i = 0; i < 4; i++)

    {

//鼠標進入信號綁定

        connect(&m_Pic[i], &PicWidget::signalEnterPicWidget, this, [=]() {

             //延長tab條到當前index

             int iCurrentPosX = 164;

             if (i != m_iCurrentPicIndex)//不是當前圖片索引時才去延長

             {

                 if (i == 0)

                 {

                     iCurrentPosX = 164;

                 }

                 else if (i == 1)

                 {

                     iCurrentPosX = 268;

                 }

                 else if (i == 2)

                 {

                     iCurrentPosX = 372;

                 }

                 else if (i == 3)

                 {

                     iCurrentPosX = 476;

                 }

                 QPropertyAnimation * linelength = new QPropertyAnimation(ui.line, "geometry");

                 linelength->setDuration(300);

                 QRect rect = ui.line->geometry();

                 linelength->setStartValue(rect);

                 linelength->setEasingCurve(QEasingCurve::Linear);

                 if (i<m_iCurrentPicIndex)//hover觸發的圖片在當前圖片左邊,x發生變化,同時長度向左延伸

                 {

                     linelength->setEndValue(QRect(iCurrentPosX, rect.top(), 32+ abs(i - m_iCurrentPicIndex) * 104, rect.height()));

                 }

                 else//hover觸發的圖片在當前圖片右邊,x不需要變化,長度向右延伸

                 {

                     linelength->setEndValue(QRect(m_iCurrentPosX, rect.top(), 32 + abs(i - m_iCurrentPicIndex) * 104, rect.height()));

                 }//執行動畫

                 linelength->start(QAbstractAnimation::DeleteWhenStopped);

             }

        });

        //鼠標放入之后沒有點擊而是離開了。還原位置

        connect(&m_Pic[i], &PicWidget::signalLeavePicWidget, this, [=]() {

             QPropertyAnimation * linelength = new QPropertyAnimation(ui.line, "geometry");

             linelength->setDuration(300);

             QRect rect = ui.line->geometry();

             linelength->setStartValue(rect);

             linelength->setEasingCurve(QEasingCurve::Linear);

             if (i >m_iCurrentPicIndex)//坐標改變,同時向右延伸

             {

                 linelength->setEndValue(QRect(m_iCurrentPosX, rect.top(),32, 4));

             }

             else//坐標不變只改變長度

             {

                 linelength->setEndValue(QRect(m_iCurrentPosX, rect.top(),32, 4));

             }

             linelength->start(QAbstractAnimation::DeleteWhenStopped);

            

 

        });

        //鼠標單擊后,切換位置,並且修改當前圖片索引和當前位置值

        connect(&m_Pic[i], &PicWidget::signalPicClicked, this, [=]() {

             QPropertyAnimation * linelength = new QPropertyAnimation(ui.line, "geometry");

             linelength->setDuration(300);

             QRect rect = ui.line->geometry();

             linelength->setStartValue(rect);

             linelength->setEasingCurve(QEasingCurve::Linear);

             if (i==0)

             {

                 m_iCurrentPosX = 164;

             }

             else if (i==1)

             {

                 m_iCurrentPosX = 268;

             }

             else if (i==2)

             {

                 m_iCurrentPosX = 372;

             }

             else if (i==3)

             {

                 m_iCurrentPosX = 476;

             }

             if (i>m_iCurrentPicIndex)

             {

                 linelength->setEndValue(QRect(m_iCurrentPosX, rect.top(), 32, 4));//

             }

             else

             {

                 linelength->setEndValue(QRect(m_iCurrentPosX, rect.top(), 32, 4));//

             }

             linelength->start(QAbstractAnimation::DeleteWhenStopped);

             m_iCurrentPicIndex = i;

             if (m_Pic[i].getPath()!="")

             {

                 SourcePicChanged(m_Pic[i].getPath());

             }  

        });

    }

 

3.3  Qt實現數字滾動動畫效果

3.3.1         應用場景說明

如下圖所示,需要顯示人臉檢測的數量,變動畫的方式實現個位數字滾動,個位由9變成0時,十位也要滾動,實現進位。當個位十位都是9時,數字不在增加,而是顯示加號+。

 

 

 

 

 

 

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

}

 

3.4 QT圖片旋轉動畫

3.4.1       應用場景說明

刪除圖片,圖片旋轉滾動到垃圾箱或者刪除按鈕時,需要有個滾動旋轉的動畫效果。需要用到QGraphicsView,QGraphicsScene,QGraphicsWidget,QLabel類,QGraphicsView類相當於黑色的框,和電視的外框類似,QGraphicsScene相當於動畫播放區域,下圖中的黑色框內部的白色區域,在這個白色區域內播放動畫。QGraphicsWidget相當於是動畫區域內的一個包裝類,將QLabel寫上文字或者通過setpixmap接口設置圖片后,添加到一個QGraphicsWidget,將QGraphicsWidget添加到QGraphicsScene,QGraphicsScene放到QGraphicsView,就可以實現旋轉圖片或者文字的動畫效果。

 

 

 

 

3.4.2      實現方法

(1)   定義旋轉角度屬性

頭文件定義

#ifndef ROTATIONVIEW_H

#define ROTATIONVIEW_H

 

 

#include <QGraphicsScene>

#include <QGraphicsView>

#include <QGraphicsWidget>

#include <QTextEdit>

#include <QPushButton>

#include <QGraphicsProxyWidget>

#include <QGraphicsLinearLayout>

 

class RotationView : public QGraphicsView

{

    Q_OBJECT

        Q_PROPERTY(int angle READ turnangle WRITE setturnangle)//自定義角度屬性

public:

    RotationView(QWidget *parent);

    ~RotationView();

    int turnangle() { return angle; };//get方法

    void setturnangle(int angle);//set方法,動畫會通過這個函數輸入插值,使圖片轉動。

    void startMove();

private:

    QGraphicsView* view = NULL;

    int angle=0;

    QGraphicsWidget *pushButton = NULL;

};

 

#endif // ROTATIONVIEW_H

 

(2)   源文件實現

 

#include "RotationView.h"

#include<windows.h>

#include <QLabel>

#include <QPropertyAnimation>

#include <QRect>

RotationView::RotationView(QWidget *parent)

    : QGraphicsView(parent)

{

    //setWindowModality(Qt::NonModal);

    setWindowFlags(Qt::FramelessWindowHint);

    QGraphicsScene* scene = new QGraphicsScene(this);

    // 創建部件,並關聯它們的信號和槽

    QPushButton *button = new QPushButton("clear");

    QLabel* plabel = new QLabel("turn me");

//  button->resize(100, 100);

    button->setGeometry(0, 0, 100, 100);

    // 將部件添加到場景中

    pushButton = scene->addWidget(plabel);

    scene->addItem(pushButton);

     view = new QGraphicsView(scene,this);

    view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

     pushButton->setParent(view);

    pushButton->setPos(100, 100);

   

    view->resize(200, 200);

    //view->setStyleSheet("border:0px;");

    view->show();

   

    //view->setStyleSheet("border:0px;");

    //setturnangle(90);

}

 

RotationView::~RotationView()

{

 

}

 

void RotationView::setturnangle(int angle)

{

    QRectF r = pushButton->boundingRect();

    //for (int i = 1; i <= 100; i++)

    //{

    pushButton->setTransform(QTransform()

        .translate(r.width() / 2, r.height() / 2)

        .rotate(angle - 360 * 1, Qt::ZAxis)

        .translate(-r.width() / 2, -r.height() / 2));

    view->update();

    //}

}

 

void RotationView::startMove()

{

    QPropertyAnimation * linelength = new QPropertyAnimation(pushButton, "geometry");

    linelength->setDuration(3000);

 

    linelength->setStartValue(QRect(5,5,50,50));

    linelength->setEndValue(QRect(100, 100, 50, 50));

    linelength->setEasingCurve(QEasingCurve::Linear);

    linelength->start(QAbstractAnimation::DeleteWhenStopped);

}

(3)   定義對象設置屬性動畫

 

#include "qtrotation.h"

#include"RotationView.h"

#include <QPropertyAnimation>

QtRotation::QtRotation(QWidget *parent)

    : QMainWindow(parent)

{

    ui.setupUi(this);

    RotationView* roview = new RotationView(this);

    roview->setGeometry(50, 50, 200, 200);

    QPropertyAnimationrotation = newQPropertyAnimation(roview"angle"this);

    rotation->setDuration(300);

    rotation->setStartValue(0);

    rotation->setEndValue(720);

    rotation->setLoopCount(20);

    rotation->setEasingCurve(QEasingCurve::Linear);

   

    connect(ui.pushRotation, &QPushButton::clicked, this, [=]() {

        roview->startMove();

        rotation->start();

    });

}

 

 

4       附錄

4.1  Qt動畫QEasingCurve的速度曲線

 https://doc.qt.io/archives/qt-4.8/qeasingcurve.html

Constant Value Description
QEasingCurve::Linear 0
Easing curve for a linear (t) function: velocity is constant.
QEasingCurve::InQuad 1
Easing curve for a quadratic (t^2) function: accelerating from zero velocity.
QEasingCurve::OutQuad 2
Easing curve for a quadratic (t^2) function: decelerating to zero velocity.
QEasingCurve::InOutQuad 3
Easing curve for a quadratic (t^2) function: acceleration until halfway, then deceleration.
QEasingCurve::OutInQuad 4
Easing curve for a quadratic (t^2) function: deceleration until halfway, then acceleration.
QEasingCurve::InCubic 5
Easing curve for a cubic (t^3) function: accelerating from zero velocity.
QEasingCurve::OutCubic 6
Easing curve for a cubic (t^3) function: decelerating to zero velocity.
QEasingCurve::InOutCubic 7
Easing curve for a cubic (t^3) function: acceleration until halfway, then deceleration.
QEasingCurve::OutInCubic 8
Easing curve for a cubic (t^3) function: deceleration until halfway, then acceleration.
QEasingCurve::InQuart 9
Easing curve for a quartic (t^4) function: accelerating from zero velocity.
QEasingCurve::OutQuart 10
Easing curve for a quartic (t^4) function: decelerating to zero velocity.
QEasingCurve::InOutQuart 11
Easing curve for a quartic (t^4) function: acceleration until halfway, then deceleration.
QEasingCurve::OutInQuart 12
Easing curve for a quartic (t^4) function: deceleration until halfway, then acceleration.
QEasingCurve::InQuint 13
Easing curve for a quintic (t^5) easing in: accelerating from zero velocity.
QEasingCurve::OutQuint 14
Easing curve for a quintic (t^5) function: decelerating to zero velocity.
QEasingCurve::InOutQuint 15
Easing curve for a quintic (t^5) function: acceleration until halfway, then deceleration.
QEasingCurve::OutInQuint 16
Easing curve for a quintic (t^5) function: deceleration until halfway, then acceleration.
QEasingCurve::InSine 17
Easing curve for a sinusoidal (sin(t)) function: accelerating from zero velocity.
QEasingCurve::OutSine 18
Easing curve for a sinusoidal (sin(t)) function: decelerating from zero velocity.
QEasingCurve::InOutSine 19
Easing curve for a sinusoidal (sin(t)) function: acceleration until halfway, then deceleration.
QEasingCurve::OutInSine 20
Easing curve for a sinusoidal (sin(t)) function: deceleration until halfway, then acceleration.
QEasingCurve::InExpo 21
Easing curve for an exponential (2^t) function: accelerating from zero velocity.
QEasingCurve::OutExpo 22
Easing curve for an exponential (2^t) function: decelerating from zero velocity.
QEasingCurve::InOutExpo 23
Easing curve for an exponential (2^t) function: acceleration until halfway, then deceleration.
QEasingCurve::OutInExpo 24
Easing curve for an exponential (2^t) function: deceleration until halfway, then acceleration.
QEasingCurve::InCirc 25
Easing curve for a circular (sqrt(1-t^2)) function: accelerating from zero velocity.
QEasingCurve::OutCirc 26
Easing curve for a circular (sqrt(1-t^2)) function: decelerating from zero velocity.
QEasingCurve::InOutCirc 27
Easing curve for a circular (sqrt(1-t^2)) function: acceleration until halfway, then deceleration.
QEasingCurve::OutInCirc 28
Easing curve for a circular (sqrt(1-t^2)) function: deceleration until halfway, then acceleration.
QEasingCurve::InElastic 29
Easing curve for an elastic (exponentially decaying sine wave) function: accelerating from zero velocity. The peak amplitude can be set with the amplitude parameter, and the period of decay by the period parameter.
QEasingCurve::OutElastic 30
Easing curve for an elastic (exponentially decaying sine wave) function: decelerating from zero velocity. The peak amplitude can be set with the amplitude parameter, and the period of decay by the period parameter.
QEasingCurve::InOutElastic 31
Easing curve for an elastic (exponentially decaying sine wave) function: acceleration until halfway, then deceleration.
QEasingCurve::OutInElastic 32
Easing curve for an elastic (exponentially decaying sine wave) function: deceleration until halfway, then acceleration.
QEasingCurve::InBack 33
Easing curve for a back (overshooting cubic function: (s+1)*t^3 - s*t^2) easing in: accelerating from zero velocity.
QEasingCurve::OutBack 34
Easing curve for a back (overshooting cubic function: (s+1)*t^3 - s*t^2) easing out: decelerating to zero velocity.
QEasingCurve::InOutBack 35
Easing curve for a back (overshooting cubic function: (s+1)*t^3 - s*t^2) easing in/out: acceleration until halfway, then deceleration.
QEasingCurve::OutInBack 36
Easing curve for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing out/in: deceleration until halfway, then acceleration.
QEasingCurve::InBounce 37
Easing curve for a bounce (exponentially decaying parabolic bounce) function: accelerating from zero velocity.
QEasingCurve::OutBounce 38
Easing curve for a bounce (exponentially decaying parabolic bounce) function: decelerating from zero velocity.
QEasingCurve::InOutBounce 39
Easing curve for a bounce (exponentially decaying parabolic bounce) function easing in/out: acceleration until halfway, then deceleration.
QEasingCurve::OutInBounce 40
Easing curve for a bounce (exponentially decaying parabolic bounce) function easing out/in: deceleration until halfway, then acceleration.
QEasingCurve::Custom 45 This is returned if the user specified a custom curve type with setCustomType(). Note that you cannot call setType() with this value, but type() can return it.


免責聲明!

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



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