QT學習筆記4(動畫)

天龍至尊發表於2020-11-30

Qt自帶的動畫框架用來做簡單的控制元件動畫效果是比較簡單易用的,像是對控制元件的位移、縮放、不透明度這些來做動畫效果。 

動畫框架結構

動畫框架結構

動畫框架由基類QAbstractAnimation以及它的兩個子類QVariantAnimation、QAnimationGroup組成。基礎動畫由QVariantAnimation的子類QPropertyAnimation來設定,再通過將多個QPropertyAnimation和QPauseAnimation組合成為動畫組(QParallelAnimationGroup、QSequentialAnimationGroup),完成一個連續的動畫。

QPropertyAnimation

QPropertyAnimation類能夠修改Qt的屬性值,如pos、geometry等屬性。設定好動畫的初值和末值,以及持續的時間後,一個屬性動畫就基本完成了。

縮放

通過修改控制元件的geometry屬性可以實現縮放效果,也可以實現位移的動畫,該屬性的前兩個值確定了控制元件左上角的位置,後兩個值確定了控制元件的大小。

 

//scale
    QPropertyAnimation *pScaleAnimation1 = new QPropertyAnimation(ui->scaleButton, "geometry");
    pScaleAnimation1->setDuration(1000);
    pScaleAnimation1->setStartValue(QRect(190, 230, 0, 0));
    pScaleAnimation1->setEndValue(QRect(120, 160, 140, 140));

位移

如果只是需要位移動畫的話,修改控制元件的pos屬性即可。pos屬性就是控制元件的左上角所在的位置。

 

//pos
    QPropertyAnimation *pPosAnimation1 = new QPropertyAnimation(ui->posButton, "pos");
    pPosAnimation1->setDuration(1000);
    pPosAnimation1->setStartValue(QPoint(360, 160));
    pPosAnimation1->setEndValue(QPoint(360, 350));
    pPosAnimation1->setEasingCurve(QEasingCurve::InOutQuad);

不透明度

Qt的控制元件沒有單獨的透明度屬性,要修改控制元件的透明度可以通過QGraphicsOpacityEffect類來實現。

 

    //opacity
    QGraphicsOpacityEffect *pButtonOpacity = new QGraphicsOpacityEffect(this);
    pButtonOpacity->setOpacity(1);
    ui->opasityButton->setGraphicsEffect(pButtonOpacity);

    QPropertyAnimation *pOpacityAnimation1 = new QPropertyAnimation(pButtonOpacity, "opacity");
    pOpacityAnimation1->setDuration(1000);
    pOpacityAnimation1->setStartValue(1);
    pOpacityAnimation1->setEndValue(0);

動畫曲線

動畫還可以設定時間的插值曲線,預設是linear,即線性運動,通過設定QEasingCurve即可。Qt提供了40種已經定義好的曲線(如果有需要也可以自定義曲線):

動畫曲線

 

pScaleAnimation1->setEasingCurve(QEasingCurve::InOutQuad);

QSequentialAnimationGroup

序列動畫分組

通過將QPropertyAnimation或者QPauseAnimation加入,構成一個按加入順序依次播放的動畫組,動畫組的總時長是各個加入動畫的總和。

 

    QSequentialAnimationGroup *pPosGroup = new QSequentialAnimationGroup(this);
    pPosGroup->addPause(500);
    pPosGroup->addAnimation(pPosAnimation1);

往返運動

Qt的動畫可以設定迴圈次數,預設的迴圈是從頭再播放一遍,往返運動可以在一個序列動畫組中加入初值末值相反的一組動畫來實現。

QParallelAnimationGroup

並行動畫組

加入並行動畫組的動畫會同時播放,動畫組的總時長是最長的動畫所需的時間。

    m_group = new QParallelAnimationGroup(this);
    m_group->addAnimation(pScaleGroup);
    m_group->addAnimation(pPosGroup);
    m_group->addAnimation(pOpacityGroup);

延時播放

在序列動畫組的開始先加入一個QPauseAnimation,再將Pause不同的序列動畫組加入並行動畫組就可以實現延時效果了。

動畫方向

預設動畫是從開始到結束這個方向播放的, 可以設定為從結束到開始播放。

m_group->setDirection(QAbstractAnimation::Backward);

綜合例子:

縮放動畫:

setMinimumSize(600,500);

    QLabel * label = new QLabel(this);

    label->setGeometry(130,130,140,140);

    label->setStyleSheet("background-color:red;");

    QPropertyAnimation *pScaleAnimation = new QPropertyAnimation(label, "geometry");
    pScaleAnimation->setDuration(500);
    pScaleAnimation->setStartValue(QRect(200,200, 0, 0));
    pScaleAnimation->setEndValue(QRect(130, 130, 140, 140));
    QSequentialAnimationGroup *sequentialAnimationGroup = new QSequentialAnimationGroup(this);
    sequentialAnimationGroup->addPause(500);
    sequentialAnimationGroup->addAnimation(pScaleAnimation);

    QParallelAnimationGroup * parallelAnimationGroup = new QParallelAnimationGroup(this);
    parallelAnimationGroup->addAnimation(sequentialAnimationGroup);

    parallelAnimationGroup->setDirection(QAbstractAnimation::Forward);
    parallelAnimationGroup->setLoopCount(-1);
    parallelAnimationGroup->start();

opacity動畫:

QLabel * label = new QLabel(this);

    label->setGeometry(130,130,140,140);

    label->setStyleSheet("background-color:red;");

    //opacity
    QGraphicsOpacityEffect * graphicsOpacityEffect = new QGraphicsOpacityEffect(this);
    graphicsOpacityEffect->setOpacity(1);
    label->setGraphicsEffect(graphicsOpacityEffect);

    QPropertyAnimation *pScaleAnimation = new QPropertyAnimation(graphicsOpacityEffect, "opacity");
    pScaleAnimation->setDuration(500);
    pScaleAnimation->setStartValue(1);
    pScaleAnimation->setEndValue(0);
    QSequentialAnimationGroup *sequentialAnimationGroup = new QSequentialAnimationGroup(this);
    sequentialAnimationGroup->addPause(500);
    sequentialAnimationGroup->addAnimation(pScaleAnimation);

    QParallelAnimationGroup * parallelAnimationGroup = new QParallelAnimationGroup(this);
    parallelAnimationGroup->addAnimation(sequentialAnimationGroup);

    parallelAnimationGroup->setDirection(QAbstractAnimation::Forward);
    parallelAnimationGroup->setLoopCount(-1);
    parallelAnimationGroup->start();

位置動畫: 

QLabel * label = new QLabel(this);

    label->setGeometry(130,130,140,140);

    label->setStyleSheet("background-color:red;");

    //pos
    QPropertyAnimation *pScaleAnimation = new QPropertyAnimation(label, "pos");
    pScaleAnimation->setDuration(500);
    pScaleAnimation->setStartValue(QPoint(130,130));
    pScaleAnimation->setEndValue(QPoint(200,200));
    QSequentialAnimationGroup *sequentialAnimationGroup = new QSequentialAnimationGroup(this);
    sequentialAnimationGroup->addPause(500);
    sequentialAnimationGroup->addAnimation(pScaleAnimation);

    QParallelAnimationGroup * parallelAnimationGroup = new QParallelAnimationGroup(this);
    parallelAnimationGroup->addAnimation(sequentialAnimationGroup);

    parallelAnimationGroup->setDirection(QAbstractAnimation::Forward);
    parallelAnimationGroup->setLoopCount(-1);
    parallelAnimationGroup->start();

相關文章