Qt進階開發:動畫框架的介紹和使用

文章目錄

    • 一、QPropertyAnimation 簡介
    • 二、基本用法
    • 三、常用屬性和方法
    • 四、支持的屬性(部分常用)
    • 五、多個動畫組合
    • 六、使用緩和曲線
    • 七、狀態機框架

一、QPropertyAnimation 簡介

#include <QPropertyAnimation>
  • QPropertyAnimation 可以讓你在一段時間內平滑地修改對象的屬性值。
  • 支持 QWidget 的 geometry、pos、size、windowOpacity 等屬性。
  • 它基于 Qt 的 屬性系統(Q_PROPERTY),只能操作那些被 Q_PROPERTY 宏聲明過的屬性。

二、基本用法

例子:讓一個按鈕平滑移動位置

QPushButton *button = new QPushButton("Click Me", this);
button->move(0, 0);QPropertyAnimation *animation = new QPropertyAnimation(button, "pos");
animation->setDuration(1000);                    // 動畫持續 1000ms
animation->setStartValue(QPoint(0, 0));          // 起始位置
animation->setEndValue(QPoint(200, 200));        // 結束位置
animation->start();                              // 啟動動畫

例子:讓一個按鈕平滑移動并且變大

#include <QPushButton>
#include <QPropertyAnimation>MainWindow::MainWindow(QWidget *parent): QWidget(parent)
{this->setFixedSize(800, 600);QPushButton* pBtn = new QPushButton("Animated Button", this);QPropertyAnimation *pAnimation = new QPropertyAnimation(pBtn, "geometry");pAnimation->setDuration(1000);pAnimation->setStartValue(QRect(0, 0, 120, 30));pAnimation->setEndValue(QRect(250, 250, 200, 60));pAnimation->start(QAbstractAnimation::DeleteWhenStopped);}

三、常用屬性和方法

在這里插入圖片描述

四、支持的屬性(部分常用)

在這里插入圖片描述

五、多個動畫組合

??在一個應用中經常會包含多個動畫,例如,要同時移動多個圖形項或者讓它們一個接一個地串行移動。使用QAnimationGroup類可以實現復雜的動畫,它的兩個子類 QSequentialAnimationGroup和QParallelAnimationGroup分別提供了串行動畫組和并行動畫組。

5.1 QParallelAnimationGroup 的使用
QParallelAnimationGroup 是 Qt 動畫框架(Qt Animation Framework)中的一個類,用于并行執行多個動畫,即多個屬性動畫同時發生。

#include <QParallelAnimationGroup>
  • 它繼承自 QAnimationGroup。
  • 內部可以添加多個 QPropertyAnimation(或其它動畫)。
  • 所有動畫會同時啟動,彼此獨立但并行執行。

基本使用示例:
示例:按鈕同時平移、縮放、透明度變化

QPushButton *button = new QPushButton("Animate", this);
button->resize(100, 30);
button->move(50, 50);// 位置動畫
QPropertyAnimation *posAnim = new QPropertyAnimation(button, "pos");
posAnim->setDuration(1000);
posAnim->setStartValue(QPoint(50, 50));
posAnim->setEndValue(QPoint(200, 150));// 大小動畫
QPropertyAnimation *sizeAnim = new QPropertyAnimation(button, "size");
sizeAnim->setDuration(1000);
sizeAnim->setStartValue(QSize(100, 30));
sizeAnim->setEndValue(QSize(200, 60));// 透明度動畫(需設置 WA_TranslucentBackground + setWindowOpacity)
QPropertyAnimation *opacityAnim = new QPropertyAnimation(button, "windowOpacity");
opacityAnim->setDuration(1000);
opacityAnim->setStartValue(1.0);
opacityAnim->setEndValue(0.3);// 并行動畫組
QParallelAnimationGroup *group = new QParallelAnimationGroup(this);
group->addAnimation(posAnim);
group->addAnimation(sizeAnim);
group->addAnimation(opacityAnim);group->start();

常用方法和屬性:
在這里插入圖片描述

完整示例:

#include <QPushButton>
#include <QPropertyAnimation>
#include <QParallelAnimationGroup>MainWindow::MainWindow(QWidget *parent): QWidget(parent)
{this->setFixedSize(800, 600);this->setWindowTitle("動畫");QPushButton *button = new QPushButton("Animate Me", this);button->resize(100, 30);button->move(50, 50);// 動畫 1:移動QPropertyAnimation *moveAnim = new QPropertyAnimation(button, "pos");moveAnim->setDuration(1000);moveAnim->setStartValue(QPoint(50, 50));moveAnim->setEndValue(QPoint(200, 150));// 動畫 2:縮放QPropertyAnimation *sizeAnim = new QPropertyAnimation(button, "size");sizeAnim->setDuration(1000);sizeAnim->setStartValue(QSize(100, 30));sizeAnim->setEndValue(QSize(200, 60));// 動畫 3:透明度QPropertyAnimation *opacityAnim = new QPropertyAnimation(button, "windowOpacity");opacityAnim->setDuration(1000);opacityAnim->setStartValue(1.0);opacityAnim->setEndValue(0.4);// 并行動畫組QParallelAnimationGroup *group = new QParallelAnimationGroup;group->addAnimation(moveAnim);group->addAnimation(sizeAnim);group->addAnimation(opacityAnim);QObject::connect(button, &QPushButton::clicked, [group]() {group->start(QAbstractAnimation::KeepWhenStopped);});
}

5.2 QSequentialAnimationGroup 的使用
QSequentialAnimationGroup 是 Qt 動畫框架(Qt Animation Framework)中的一個動畫組類,用于 順序地執行多個動畫 —— 即一個動畫結束后,自動執行下一個動畫,依此類推。它特別適用于需要連續步驟式動畫效果的場景,比如一個按鈕先移動 → 再放大 → 再變淡。

#include <QSequentialAnimationGroup>
  • 它繼承自 QAnimationGroup。
  • 內部包含多個動畫(如 QPropertyAnimation)。
  • 每個動畫順序執行,一個結束后自動播放下一個。

基本使用示例:
示例:按鈕先移動 → 再變大 → 再淡出

QPushButton *button = new QPushButton("Animate", this);
button->move(50, 50);
button->resize(100, 30);// 動畫 1:移動
QPropertyAnimation *moveAnim = new QPropertyAnimation(button, "pos");
moveAnim->setDuration(1000);
moveAnim->setStartValue(QPoint(50, 50));
moveAnim->setEndValue(QPoint(200, 150));// 動畫 2:縮放
QPropertyAnimation *sizeAnim = new QPropertyAnimation(button, "size");
sizeAnim->setDuration(800);
sizeAnim->setStartValue(QSize(100, 30));
sizeAnim->setEndValue(QSize(200, 60));// 動畫 3:透明度
QPropertyAnimation *opacityAnim = new QPropertyAnimation(button, "windowOpacity");
opacityAnim->setDuration(800);
opacityAnim->setStartValue(1.0);
opacityAnim->setEndValue(0.3);// 順序動畫組
QSequentialAnimationGroup *group = new QSequentialAnimationGroup(this);
group->addAnimation(moveAnim);
group->addAnimation(sizeAnim);
group->addAnimation(opacityAnim);group->start();

常用方法:
在這里插入圖片描述
插入等待/暫停動畫:
可以在兩個動畫之間插入暫停

group->addAnimation(moveAnim);
group->insertPause(500);  // 停 500ms
group->addAnimation(sizeAnim);

完整可運行示例:

#include <QPushButton>
#include <QPropertyAnimation>
#include <QSequentialAnimationGroup>MainWindow::MainWindow(QWidget *parent): QWidget(parent)
{this->setFixedSize(800, 600);this->setWindowTitle("動畫");QPushButton *button = new QPushButton("Start Animation", this);button->move(50, 50);button->resize(100, 30);// 動畫組定義QSequentialAnimationGroup *group = new QSequentialAnimationGroup;// 移動動畫QPropertyAnimation *moveAnim = new QPropertyAnimation(button, "pos");moveAnim->setDuration(1000);moveAnim->setStartValue(QPoint(50, 50));moveAnim->setEndValue(QPoint(200, 150));// 暫停動畫group->addAnimation(moveAnim);group->insertPause(1, 500);// 縮放動畫QPropertyAnimation *sizeAnim = new QPropertyAnimation(button, "size");sizeAnim->setDuration(800);sizeAnim->setStartValue(QSize(100, 30));sizeAnim->setEndValue(QSize(200, 60));group->addAnimation(sizeAnim);// 透明度動畫QPropertyAnimation *opacityAnim = new QPropertyAnimation(button, "windowOpacity");opacityAnim->setDuration(1000);opacityAnim->setStartValue(1.0);opacityAnim->setEndValue(0.3);group->addAnimation(opacityAnim);QObject::connect(button, &QPushButton::clicked, [group]() {group->start(QAbstractAnimation::KeepWhenStopped);});
}

補充說明:

  • 動畫可重復播放:group->setLoopCount(n);
  • 動畫結束信號:connect(group, &QSequentialAnimationGroup::finished, …)
  • 可嵌套其他動畫組形成復雜流程(如先順序 → 同時多個動畫)

5.3 多個動畫的使用實例
多個組件依次動畫執行:

#include <QPushButton>
#include <QVBoxLayout>
#include <QPropertyAnimation>
#include <QSequentialAnimationGroup>MainWindow::MainWindow(QWidget *parent): QWidget(parent)
{this->setFixedSize(800, 600);this->setWindowTitle("動畫");// 創建三個按鈕QPushButton *btn1 = new QPushButton("Button 1", this);QPushButton *btn2 = new QPushButton("Button 2", this);QPushButton *btn3 = new QPushButton("Button 3", this);btn1->move(20, 50);btn2->move(20, 100);btn3->move(20, 150);// 創建動畫組QSequentialAnimationGroup *group = new QSequentialAnimationGroup(this);// 按鈕 1 動畫QPropertyAnimation *anim1 = new QPropertyAnimation(btn1, "pos");anim1->setDuration(500);anim1->setEndValue(QPoint(250, 50));// 按鈕 2 動畫QPropertyAnimation *anim2 = new QPropertyAnimation(btn2, "pos");anim2->setDuration(500);anim2->setEndValue(QPoint(250, 100));// 按鈕 3 動畫QPropertyAnimation *anim3 = new QPropertyAnimation(btn3, "pos");anim3->setDuration(500);anim3->setEndValue(QPoint(250, 150));// 插入動畫到順序組group->addAnimation(anim1);group->addAnimation(anim2);group->addAnimation(anim3);// 點擊任意按鈕啟動動畫connect(btn1, &QPushButton::clicked, this, [=]{group->start();});connect(btn2, &QPushButton::clicked, this, [=]{group->start();});connect(btn3, &QPushButton::clicked, this, [=]{group->start();});
}

在這里插入圖片描述

六、使用緩和曲線

??在 Qt 的動畫系統中,緩和曲線(Easing Curve) 用于控制動畫過程中屬性值隨時間的變化速度,也就是“動畫節奏感”。這通過 QEasingCurve 類實現,可以讓動畫效果更自然、生動,比如:

  • 加速、減速(常見于 UI 移動)
  • 彈跳、回彈(常見于游戲 UI)
  • 彈性伸縮(擬物風格)

設置緩和曲線的方法:
每個 QPropertyAnimation 都可以通過如下方式設置緩和曲線:

QPropertyAnimation *anim = new QPropertyAnimation(widget, "pos");
anim->setDuration(1000);
anim->setStartValue(QPoint(0, 0));
anim->setEndValue(QPoint(200, 200));// 設置緩和曲線
anim->setEasingCurve(QEasingCurve::OutBounce);

常用緩和曲線類型:
在這里插入圖片描述
示例:三種不同節奏的移動動畫

#include <QPushButton>
#include <QPropertyAnimation>MainWindow::MainWindow(QWidget *parent): QWidget(parent)
{this->setFixedSize(800, 600);this->setWindowTitle("動畫");QStringList labels = { "Linear", "OutBounce", "InOutBack" };for (int i = 0; i < 3; ++i) {QPushButton *btn = new QPushButton(labels[i], this);btn->move(20, 50 + i * 50);QPropertyAnimation *anim = new QPropertyAnimation(btn, "pos", this);anim->setDuration(1000);anim->setStartValue(QPoint(20, 50 + i * 50));anim->setEndValue(QPoint(250, 50 + i * 50));anim->setEasingCurve(QEasingCurve::OutBounce);anim->start(QAbstractAnimation::DeleteWhenStopped);}
}

此時運行程序會發現,它會使按鈕部件就像從開始位置掉落到結束位置的皮球一樣出現彈跳效果。

七、狀態機框架

什么是狀態機?
狀態機(State Machine)是一種數學模型,用來表示對象的狀態和狀態之間的切換規則。在 Qt 中,狀態機由以下核心元素組成:

  • QStateMachine:狀態機管理器;
  • QState / QFinalState:狀態;
  • QAbstractTransition:狀態間的過渡;
  • QSignalTransition:基于信號的過渡;
  • QHistoryState:記住某個狀態組最后進入的子狀態(可用于“返回上次狀態”);
  • QState::assignProperty():狀態進入時自動設置對象屬性(常用于動畫或 UI 狀態變化);

簡單使用示例:
場景:點擊按鈕在紅色和綠色之間切換

#include <QPushButton>
#include <QStateMachine>
#include <QState>
#include <QSignalTransition>MainWindow::MainWindow(QWidget *parent): QWidget(parent)
{this->setFixedSize(800, 600);this->setWindowTitle("動畫");QPushButton* pBtn = new QPushButton("Toggle Color", this);QStateMachine *pMachine = new QStateMachine(this);QState *redState = new QState();redState->assignProperty(pBtn, "styleSheet", "background-color: red");QState *greenState = new QState();greenState->assignProperty(pBtn, "styleSheet", "background-color: green");// 狀態切換redState->addTransition(pBtn, &QPushButton::clicked, greenState);greenState->addTransition(pBtn, &QPushButton::clicked, redState);// 添加狀態并設置初始狀態pMachine->addState(redState);pMachine->addState(greenState);pMachine->setInitialState(greenState);pMachine->start();
}

狀態機和動畫結合

結合狀態機和動畫的關鍵點:

  • 利用 QState::assignProperty() 設置狀態進入時的屬性值;
  • 使用 QStateMachine::addDefaultAnimation() 添加動畫,動畫會在狀態切換時自動播放;
  • 動畫可作用于多種屬性(位置、大小、顏色、透明度等);
  • 結合定時器和事件可以實現更復雜動畫狀態切換。
#include <QPushButton>
#include <QStateMachine>
#include <QState>
#include <QPropertyAnimation>MainWindow::MainWindow(QWidget *parent): QWidget(parent)
{this->setFixedSize(800, 600);this->setWindowTitle("動畫");QPushButton *pBtn = new QPushButton("Click me", this);pBtn->setGeometry(100, 100, 150, 50);pBtn->show();QStateMachine *pMachine = new QStateMachine(this);// 狀態1:按鈕紅色,左上角QState *state1 = new QState();state1->assignProperty(pBtn, "geometry", QRect(100, 100, 150, 50));state1->assignProperty(pBtn, "styleSheet", "background-color: red");// 狀態2:按鈕綠色,右下角QState *state2 = new QState();state2->assignProperty(pBtn, "geometry", QRect(400, 300, 150, 100));state2->assignProperty(pBtn, "styleSheet", "background-color: green");// 狀態切換state1->addTransition(pBtn, &QPushButton::clicked, state2);state2->addTransition(pBtn, &QPushButton::clicked, state1);pMachine->addState(state1);pMachine->addState(state2);pMachine->setInitialState(state1);// 添加動畫,自動在狀態切換時播放QPropertyAnimation *anim = new QPropertyAnimation(pBtn, "geometry");anim->setDuration(500);anim->setEasingCurve(QEasingCurve::InOutQuad);pMachine->addDefaultAnimation(anim);pMachine->start();
}

效果顯示:
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/84443.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/84443.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/84443.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

IP選擇注意事項

IP選擇注意事項 MTP、FTP、EFUSE、EMEMORY選擇時&#xff0c;需要考慮以下參數&#xff0c;然后確定后選擇IP。 容量工作電壓范圍溫度范圍擦除、燒寫速度/耗時讀取所有bit的時間待機功耗擦寫、燒寫功耗面積所需要的mask layer

Flask RESTful 示例

目錄 1. 環境準備2. 安裝依賴3. 修改main.py4. 運行應用5. API使用示例獲取所有任務獲取單個任務創建新任務更新任務刪除任務 中文亂碼問題&#xff1a; 下面創建一個簡單的Flask RESTful API示例。首先&#xff0c;我們需要創建環境&#xff0c;安裝必要的依賴&#xff0c;然后…

filebeat原理架構

Filebeat 是基于 Golang 開發的輕量級日志采集 Agent&#xff0c;其核心架構設計圍繞高效、可靠地采集與轉發日志數據&#xff0c;主要組件和工作流程如下&#xff1a; ?一、核心架構組件? ?輸入 (Inputs)? 負責監控指定的日志源&#xff08;如文件路徑、日志文件&#x…

Air8000開發板新資料開放!多功能+高擴展特性全面解鎖

Air8000開發板最新技術資料正式向開發者開放。這個開發板集多功能與高擴展性于一身&#xff0c;將為物聯網、嵌入式系統等領域的創新項目提供更強大的技術支持&#xff0c;助力開發者快速實現創意落地。 工程師朋友們&#xff0c;Air8000開發板“多功能集成高擴展性”&#xff…

如何遷移Cordova應用到HarmonyOS 5 以及遷移時常見的問題?

以下是 Cordova 應用遷移至 HarmonyOS 5 的完整方案及常見問題解決方案&#xff0c;結合最新技術實踐整理&#xff1a; 一、遷移流程 1. ?方案選擇? ?方案??適用場景??操作復雜度??Android 兼容層方案?簡單應用快速上線低&#xff08;無需修改代碼&#xff09;?原…

板凳-------Mysql cookbook學習 (十--4)

6.3 設置客戶端時區 --客戶端位于不同時區需要注意&#xff0c;如果位于同一時區則不需要關心 mysql> drop table if exists t; Query OK, 0 rows affected (0.06 sec)mysql> create table t (ts timestamp); Query OK, 0 rows affected (0.05 sec)mysql> insert int…

如何根據excel表生成sql的insert腳本

根據excel自帶的vba宏進行操作 首先altF11 點擊插入~模塊 錄取執行語句 Sub GenerateSQL()Dim lastRow As IntegerlastRow Cells(Rows.Count, 1).End(xlUp).RowFor i 2 To lastRow 假設第一行是標題Cells(i, "S").Value "INSERT INTO table_name (ID, RE…

React hook之useRef

React useRef 詳解 useRef 是 React 提供的一個 Hook&#xff0c;用于在函數組件中創建可變的引用對象。它在 React 開發中有多種重要用途&#xff0c;下面我將全面詳細地介紹它的特性和用法。 基本概念 1. 創建 ref const refContainer useRef(initialValue);initialValu…

開疆智能ModbusTCP轉Canopen網關連接AB PLC與臺達伺服通訊案例

本案例是羅克韋爾PLC通過開疆智能ModbusTCP轉Canopen網關連接臺達A2伺服的配置案例。 配置方法&#xff1a; 首先打開PLC配置軟件“Studio5000”并新建項目導入通訊文件 對功能塊進行設置 填寫本地IP地址以及服務區IP地址以及寄存器 填寫寄存器地址數量及使能 確認無誤后將配置…

用 LoRA 對 Qwen2.5-VL 模型進行SFT - LoRA微調流程

用 LoRA 對 Qwen2.5-VL 模型進行SFT - LoRA微調流程 flyfish ┌──────────────────────────────────────────────────────────────────────────┐ │ 環境準備與啟動 …

熵最小化Entropy Minimization (二): 案例實施

前面介紹了熵最小化、常用的權重函數匯總、半監督學習&#xff1a;低密度分離假設 (Low-Density Separation Assumption)、標簽平滑、信息最大化等相關的知識點&#xff0c;本文采用一個MNIST10分類的數據集來進一步體會它們的效果。 案例實施 對比方法 純監督學習方法&…

聯邦學習聚合參數操作詳解

聯邦學習中常見的模型聚合操作&#xff0c;具體用于對來自多個客戶端的模型更新進行聚合&#xff0c;以得到全局模型。在聯邦學習框架下&#xff0c;多個客戶端在本地訓練各自的模型后&#xff0c;會將模型更新&#xff08;通常是模型的權重&#xff09;發送到中央服務器&#…

藍牙 BLE 掃描面試題大全(2):進階面試題與實戰演練

前文覆蓋了 BLE 掃描的基礎概念與經典問題藍牙 BLE 掃描面試題大全(1)&#xff1a;從基礎到實戰的深度解析-CSDN博客&#xff0c;但實際面試中&#xff0c;企業更關注候選人對復雜場景的應對能力&#xff08;如多設備并發掃描、低功耗與高發現率的平衡&#xff09;和前沿技術的…

基于Flask實現的醫療保險欺詐識別監測模型

基于Flask實現的醫療保險欺詐識別監測模型 項目截圖 項目簡介 社會醫療保險是國家通過立法形式強制實施&#xff0c;由雇主和個人按一定比例繳納保險費&#xff0c;建立社會醫療保險基金&#xff0c;支付雇員醫療費用的一種醫療保險制度&#xff0c; 它是促進社會文明和進步的…

機房斷電后 etcd 啟動失敗的排查與快速恢復實錄

目錄 機房斷電后 etcd 啟動失敗的排查與快速恢復實錄 背景與問題起因 報錯分析 解決方案&#xff1a;刪除 member 數據重新初始化 步驟 1&#xff1a;停止 etcd 容器或服務 步驟 2&#xff1a;刪除 member 目錄 步驟 3&#xff1a;重啟 etcd 服務 附加提醒 總結與后續…

Linux上并行打包壓縮工具

文章目錄 Linux上并行打包壓縮工具1. **Pigz (Parallel gzip)**2. **Pbzip2 (Parallel bzip2)**3. **Pixz (Parallel xz)**4. **Zstd (支持多線程)**5. **GNU Parallel 傳統工具**6. **Fastest Tools (綜合建議)**注意事項&#xff1a; tar和zstd多線程壓縮和解壓**1. 多線程壓…

【K8S系列】K8S中Service 無法訪問問題的深度分析

摘要 &#xff1a; 本文是關于 Kubernetes 中 Service 無法訪問問題的深度分析&#xff0c;結合根本原因、診斷策略與解決方案的系統性指南&#xff1a; Kubernetes Service 訪問故障全景解析&#xff1a;從底層機制到實戰修復 Service 作為 Kubernetes 集群內網絡通信的核心抽…

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解題思路2. 代碼實現 題目鏈接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解題思路 這一題其實就是一個腦筋急轉彎&#xff0c;要想要能夠將所有的電腦解鎖&#x…

進行性核上性麻痹護理指南:全維度守護健康

進行性核上性麻痹是一種罕見的神經系統退行性疾病&#xff0c;會導致患者出現運動障礙、吞咽困難、認知障礙等癥狀。科學的健康護理對延緩病情發展、提升患者生活質量至關重要。 飲食護理&#xff1a;由于患者常存在吞咽困難&#xff0c;食物應選擇糊狀、軟爛的類型&#xff0c…

【淺析賽題,國賽一等獎水平:思路+模型:】2025 年第八屆河北省研究生數學建模競賽:A 題 基于圖論的復雜網絡分析與可視化建模

問題一&#xff1a;社交網絡拓撲結構分析與影響力評估 基礎模型 有向加權圖構建&#xff1a;將用戶設為節點&#xff0c;互動關系為有向邊&#xff0c;以互動頻率&#xff08;如一定時間內點贊、評論、轉發次數&#xff09;或加權求和&#xff08;賦予不同互動類型不同權重&a…