QT中的動畫機制

目錄

 

一、qt框架中主要動畫類

二、各個類的主要作用

三、關於窗體的透明屬性

四、qt框架的動畫的一些弊端


一、qt框架中主要動畫類

  • QPropertyAnimation
  • QSequentialAnimationGroup
  • QParallelAnimationGroup

二、各個類的主要作用

1、QPropertyAnimation

該類爲屬性動畫類,顧名思義,qt的動畫是基於窗體的某個屬性,對該屬性進行相應的變化來使得窗體動起來。同時,在運用動畫時必要的步驟便是爲某個窗體綁定一種動畫。

舉個栗子,比如widget窗體的屬性geometry,該屬性用於控制窗體在屏幕上的顯示位置,該屬性有4個參數,分別爲x,y,w,h。即窗體在屏幕上的(x,y)座標點以及窗體的初始化寬和高,當窗體的座標點發生變化,而寬,高不變時,即可看到平移的動畫效果;當加入寬高元素變化時,例如寬高由0變化至窗體正常大小時,即可看到縮放的動畫效果。

QPropertyAnimation* pScaleAnimation = new QPropertyAnimation(ui->widget, "geometry");
pScaleAnimation->setDuration(1000);
pScaleAnimation->setStartValue(QRect(1920 / 2, 1080 / 2, 0, 0));
pScaleAnimation->setEndValue(QRect(0, 0, 1920, 1080));
pScaleAnimation->setEasingCurve(QEasingCurve::InOutQuad);

以上代碼實現了窗體的縮放動畫,首先new一個屬性動畫類,並將widget綁定於該動畫,且綁定屬性爲“geometry”;其次規定該動畫的持續時間,單位爲ms;然後規定動畫的起始座標以及結束座標;最後爲該動畫選擇一種運動類型,qt官方提供了很多種不同的插值曲線來簡化動畫的製作,例如加速、減速、彈跳等插值曲線,來讓整個動畫框架顯得更加完善。具體可參考官方文檔中描述來選擇自己所需要的動畫曲線,官方文檔鏈接爲:https://doc.qt.io/qt-5/qeasingcurve.html。

2、QSequentialAnimationGroup

該類爲串行動畫組。當我們不滿足於單一的縮放、平移效果,想擁有類似於Android平臺的動畫特效時,便需要用到串行動畫組,通過將各個屬性動畫加入到該串行動畫組中,依據加入動畫組中的先後順序,便可以呈現出更爲複雜而有趣的動畫,例如縮放展開動畫+平移動畫+縮放消失動畫整個流暢的過程。但要注意的是對於串行動畫組來說,在同一時間,只能有一個窗體的動畫在運行,因爲其爲“串行”。

QSequentialAnimationGroup* pScaleGroup = new QSequentialAnimationGroup(this);
pScaleGroup->addAnimation(pScaleAnimation1);
pScaleGroup->addAnimation(pScaleAnimation2);
pScaleGroup->addAnimation(pScaleAnimation3);

以上代碼展示瞭如何將已定義好的屬性動畫加入到串行動畫組中。

3、QParallelAnimationGroup

該類爲並行動畫組。很多時候我們想要的動畫也並不是單一的同一時間只能看到一個窗體動來動去,我們希望能夠像Android平臺那樣豐富而又絢麗的多窗體動畫,那麼這個時候就需要用到該類了。通過將屬性動畫或者甚至是串行動畫組加入到並行動畫組中,我們便可以得到更加複雜,且窗體不限的動畫效果,這個時候,在同一時間,便可以有多個窗體進行動畫的展示。

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

以上代碼展示瞭如何將已定義好的串行動畫組加入到並行動畫組中。

4、動畫的運行

那麼以上的代碼只是用來聲明一個或多個複雜的動畫,那麼如何才能讓動畫真正動起來呢?那麼就需要按照如下的方式進行調用,在下面的代碼中還有對動畫正向或者反向的設置,qt已經爲我們封裝了一個宏用於反向動畫的播放,而不必我們再次實現反向動畫的聲明和座標的計算等麻煩事情。另外可以設置動畫運行的次數,即反覆播放的次數。通過start()函數來讓動畫實際動起來。

QParallelAnimationGroup* m_group;
m_group->setDirection(QAbstractAnimation::Forward);
m_group->setLoopCount(1);
m_group->start();

以上代碼展示瞭如何讓動畫動起來。

三、關於窗體的透明屬性

透明屬性需要另外的類參與來設置。

QGraphicsOpacityEffect* pWidgetOpacity = new QGraphicsOpacityEffect(this);
pWidgetOpacity->setOpacity(1);
widget->setGraphicsEffect(pWidgetOpacity);
QPropertyAnimation* pOpacityAnimation = new QPropertyAnimation(pWidgetOpacity, "opacity");
pOpacityAnimation->setDuration(s_time * 1000);
pOpacityAnimation->setStartValue(1);
pOpacityAnimation->setEndValue(0);
pOpacityAnimation->setEasingCurve(QEasingCurve::Linear);

以上代碼實現了對窗體的透明度的屬性的綁定以及由不透明到透明的漸變動畫。

四、qt框架的動畫的一些弊端

雖然qt提供了這些動畫類來簡化動畫的製作,但是對於桌面應用來講,無法做到像Android平臺一樣的動畫流暢度,其動畫效果的流暢程度只能說一般,而且在加載部分圖片資源到窗體上的時候,如果圖片資源較大,則會導致App佔用內存較高,動畫播放卡頓的現象十分嚴重。且特別要吐槽一下每個動畫都必須要綁定窗體,無法做到某個位置的全部窗體適配,這一點是十分不方便的,在編寫項目過程中令人十分頭疼。在一些性能較差的嵌入式端平臺上,qt項目的內存佔用率以及cpu佔用率一度高居不下,這實在是很煩惱的一件事情。

另外,在動畫中難免不了對一些座標進行計算以及控制,這些點都十分麻煩以及繁瑣,最近也採用了狀態機的方式來製作動畫,有時間再對狀態機機制進行一些彙總,個人用起來感覺利用狀態機來製作類似Android的動畫會比較簡單方便,但是狀態機的動畫效果仍然有很多地方不方便。

 

 

發佈了52 篇原創文章 · 獲贊 6 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章