1. 程式人生 > >Qt 幀動畫 (QWidget)

Qt 幀動畫 (QWidget)

引言

動畫很讓人煩惱,在Qt中,已經給出了很多簡單的動畫,例如 QPropertyAnimation 類實現的動畫,但是還不夠智慧,不是我想要的,相信你也有同感,今天我們就來實現自定義動畫類來方便我們日後的開發。

簡介

作業系統:window7 x64
程式設計IDE:Qt Creator 4.2.1
Qt版本: 5.0.3 · 5.3.0 · 5.8.0
最後更新:2017年4月14日

示例

效果

  • 效果展示
    為了減小檔案,我對gif動畫做了一些刪減,所以看起來好像有跳幀的現象,其實並沒有。

    Qt動畫實現效果展示圖

  • 所需資源

    甌裔

甌裔

  • 封裝後引用

    封裝後我只需要五行程式碼即可顯示自定義的動畫了。

#include "widget.h"
#include "ui_widget.h"
#include "customdynamicwidget.h"
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    dynamicAnima_ = new CustomDynamicWidget(this);
    dynamicAnima_->setAnimation(QPixmap(":/q/level_num.png"
),10,100); dynamicAnima_->setGeometry(41,41,41,41); dynamicAnima_->show(); // 順時針播放每幀 dynamicAnima_->startClockwise(); } Widget::~Widget() { delete ui; }

下載

擁有了這個類,你就擁有了所有動畫!

程式碼:下載
圖片:下載

原理

  • 實現關聯
  #include <QTimer>
  #include <QPainter>
  #include <QWidget>
  • 邏輯流程

    1. 等比例切割傳入的圖片元素

      • 建立定時器,並關聯更新槽
      • 等比例對圖片進行切割
    2. 利用了定時器(QTimer) 定時更新介面

      • 定時器被觸發
      • 辨別當前幀
      • 若是尾幀辨別是否啟用了動畫無限迴圈
      • 修改幀
      • 更新介面
    3. 重寫paintEvent函式,利用畫家類(QPainter) 完成自繪。

      • 獲取當前幀的對應圖片
      • 更新當前視窗

實現

邏輯函式

  • 1、等比例切割傳入的圖片元素
/*
* 設定動畫
* setAnimation
* _pix:圖片
* _count:圖片幀數
* _msec:切換速度 (毫秒 1秒 = 1000毫秒)
*/
void CustomDynamicWidget::setAnimation(const QPixmap &_pix, const short _count, const int _msec) {
    count_ = _count;
    currentIndex_ = 0;

    if (!pixList_.empty()) {
        pixList_.clear();
    }
    else {
        /*  順時針動畫關聯  */
        clockTimer_ = new QTimer(this);
        clockTimer_->setInterval(_msec);
        connect(clockTimer_, SIGNAL(timeout()), this, SLOT(updateClockwise()));

        /*  逆時針動畫關聯  */
        counterclockTimer_ = new QTimer(this);
        counterclockTimer_->setInterval(_msec);
        connect(counterclockTimer_, SIGNAL(timeout()), this, SLOT(updateCounterclockwise()));
    }

    /*  鏈式動畫圖示分離  */
    for(short i=0; i != _count; ++i) {
        pixList_.append(_pix.copy(i * (_pix.width() / _count), 0,
                        _pix.width() / _count, _pix.height()));
    }

    currentPix_ = pixList_.at(0);
    this->setGeometry(0,0,currentPix_.width(),currentPix_.height());

    update();

}
  • 2、利用了定時器(QTimer) 定時更新介面
void CustomDynamicWidget::updateClockwise(void) {
    do {
        if (currentIndex_ < count_ && currentIndex_ >= 0) {
            /*  更新幀  */
            currentPix_ = pixList_.at(currentIndex_);
            update();

            /*  判斷幀數  */
            if (currentIndex_ >= (count_ - 1)) {
                if(isLoop_) {
                    currentIndex_ = 0;
                    return;
                }
                break;
            }

            /*  跳幀  */
            ++currentIndex_;
            return;
        }
    #ifndef QT_NO_DEBUG
        else {
            qDebug() << __FUNCTION__ << "waring: 錯誤的下標" << currentIndex_;
        }
    #endif
    } while(false);

    clockTimer_->stop();
    currentIndex_ = 0;
    emit clockwiseFinished();
}
  • 3、重寫paintEvent函式,利用畫家類(QPainter) 完成自繪。
void CustomDynamicWidget::paintEvent(QPaintEvent *) {
    QPainter painter(this);
    painter.drawPixmap(rect(), currentPix_);
}
  • 標頭檔案
#ifndef CUSTOMDYNAMICWIDGET_H
#define CUSTOMDYNAMICWIDGET_H

/*
* 自定義動畫類
* 作者:甌裔
* 郵箱:[email protected]
* CSDN:http://blog.csdn.net/csnd_ayo
* 建立時間:2017年1月9日 19:34:13
* QT版本:5.0.2 ~ 5.8.0
*/

#include <QWidget>

/*
* 說明:
*   當前類是針對一張鏈式圖片
*   鏈式圖片預設為8幀,預設0.1秒播放一幀
*   可以根據自己需要進行設定與更改
*   進行自動切割,迴圈播放每一幀
*
* 示例:
*   類內宣告 CustomDynamicWidget* dynamicAnima_
*   ui->setupUi(this);
*   dynamicAnima_ = new CustomDynamicWidget(this);
*   dynamicAnima_->setAnimation(QPixmap(":/res/loading.png"),8,100);
*   dynamicAnima_->setGeometry(100,100,300,300);
*   dynamicAnima_->show();
*   // 順時針播放每幀
*   dynamicAnima_->startClockwise();
*/

class QTimer;
class CustomDynamicWidget : public QWidget
{
    Q_OBJECT
public:

    explicit CustomDynamicWidget(QWidget *parent = 0);
    /*
    * 設定動畫圖示
    * 函式名:setAnimation
    * 引數 _pix:圖示例項
    * 引數 _count:圖示例項動畫幀數
    * 引數 _msec:動畫切幀速度 (毫秒級)
    */
    void setAnimation(const QPixmap& _pix, const short _count = 8, const int _msec = 100);

    /*  開始動畫(順時針)  */
    void startClockwise(void);
    /*  開始動畫(逆時針)  */
    void startCounterclockwise(void);
    /*  停止動畫  */
    void stop(void);
    /*  設定動畫無限迴圈  */
    void setLoop(const bool _isLoop = false) { isLoop_ = _isLoop; }

signals:

    /*  順時針動畫結束  */
    void clockwiseFinished(void);
    /*  逆時針動畫結束  */
    void counterclockwiseFinished(void);

private slots:

    /*  順時針動畫槽  */
    void updateClockwise(void);
    /*  逆時針動畫槽  */
    void updateCounterclockwise(void);

protected:

    void paintEvent(QPaintEvent *);

private:

    /*  動畫(是否無限迴圈)  */
    bool isLoop_;
    /*  圖示列表數量  */
    short count_;
    /*  當前展示的圖示下標  */
    short currentIndex_;
    /*  控制順時針槽定時器  */
    QTimer *clockTimer_;
    /*  控制逆時針槽定時器  */
    QTimer *counterclockTimer_;
    /*  當前展示的圖示  */
    QPixmap currentPix_;
    /*  圖示列表  */
    QList<QPixmap> pixList_;

};

#endif // CUSTOMDYNAMICWIDGET_H

相關推薦

Qt 動畫 QWidget

引言 動畫很讓人煩惱,在Qt中,已經給出了很多簡單的動畫,例如 QPropertyAnimation 類實現的動畫,但是還不夠智慧,不是我想要的,相信你也有同感,今天我們就來實現自定義動畫類來方便我們日後的開發。 簡介 作業系統:windo

Android 學習之逐動畫Frame

http sta ram override start pub fill creat 代碼 幀動畫就是將一些列圖片。依次播放。利用肉眼的“視覺暫留”的原理,給用戶的感覺是動畫的錯覺,逐幀動畫的原理和早期的電影原理是一樣的。 a:須要定義逐幀動畫,能夠通過代碼定義。也能夠

Cocos2d-JS中使用CocosStudio資源——動畫1

在本篇部落格中,我們將通過一個在Cocos2d-JS中使用從CocosStudio匯出的幀動畫資源的例子,來簡要介紹以下內容:利用ActionTimeLine進行動畫切割,如何使用匯出的幀動畫資源。關於幀動畫,由於內容繁雜。我們將分為兩篇進行介紹。本篇將主

自己定義View時,用到Paint Canvas的一些溫故,簡單的動畫動畫一 ,&quot;掏糞男孩Gif&quot;順便再提提onWindowFocusChanged

eat android 內容 rri generated 簡單的 fadein spl onclick 轉載請註明出處:王亟亟的大牛之路 之前在繪畫的過程中提到了靜態的旋轉啊,縮放啊,平移等一些效果。那麽自己定義的View當然也有動態的效果也就是我們的

Qt開場動畫gif效果的實現

    Qt自己提供了一個開場動畫的類QSplashScreen,可以實現簡單的圖片開場的效果,但是是靜態的圖片。 Qt播放gif格式圖片是利用的QMovie實現的。因此利用QMoviee和QTimer,每隔一段時間將QSplashScreen重繪一次,來實現gi

筆記八 :EgretH5通用MVC框架的入門操作:製作並播放動畫UI部分

前言:幀動畫是遊戲中最常用的的兩種動畫播放形式之一,其中一種是骨骼動畫,一種就是幀動畫了,在H5遊戲中,幀動畫一般用於UI介面的操作動畫,人物技能,特效什麼的。本筆記基於通用MVC框架,以及“筆記一”中的scene搭建的範例,基於原始碼我的資源中的《筆記一到筆記七原始碼》,最

Android三種動畫View Animation(補間動畫) 、Drawable Animation(動畫) 、Property Animation(屬性動畫)

轉載:http://blog.csdn.net/lmj623565791/article/details/38092093 三種動畫的優缺點: (1)Frame Animation(幀動畫)主要用於播放一幀幀準備好的圖片,類似GIF圖片,優點是使用簡單

Android 動畫動畫、補間動畫

1.Frame Animation(幀動畫) 幀動畫就是把多張圖片在定義的短時間內完成順序播放,最終呈現在視覺上的動態效果;幀動畫首先得具有圖片資源。 下面是幀動畫在Android開發中的具體實現: (1)activity_main.xml檔案: <

Android 動畫Frame Animation 動畫停止在第一

專案中遇到的問題: 需求: 做一個聊天頁面,要求播放語音時,有一個類似於喇叭的動畫,從小到大不停迴圈,語音播放完,動畫停止在第一幀。當點選正在播放的語音時,語音停止,動畫回覆到第一幀(回覆到第一幀是難點) 實現:用Frame Animation   可以在Java程式碼中新

Qt 旋轉動畫純程式碼

簡述 初嘗QT不甚歡喜,CSDN上有非常多的朋友在為QT做出貢獻,我也願意以主觀角度來分享QT,讓QT變得更好。 該原始碼系作者個人撰寫,使用時請尊重作者,不要隨意篡改關於作者的資訊。 獲取方式 為了讓你我都能得到提升,請您在評論區留下對我的建議,並附上您可愛的郵箱,

核心動畫-關鍵動畫

一、簡單介紹 CAKeyframeAnimation是CApropertyAnimation的子類,跟CABasicAnimation的區別是:CABasicAnimation只能從一個數值(fromValue)變到另一個數值(toValue),而CAKeyf

Android Studio之Activity切換動畫

文章 oid out size ref intel tar studio anim 1、上一篇文章“Android Studio之多個Activity的滑動切換(二)”中實現了多個activity之間的滑動切換,可是新切換出的activity大多是從右側進入 2、我們能

js動畫速度

fun esc move keywords nload desc func cache scale <!DOCTYPE html><html><head><meta charset="utf-8" /><meta htt

CSS3動畫:波浪效果

col -1 loading ack css代碼 code load width ase 實現效果 如圖所示: 首先得準備三張圖,一張是淺黃色的背景圖loading_bg.png,一張是深紅色的圖loading.png,最後一張為bolang.png。 css代碼

Qt 3D教程初步顯示3D的內容

初始 應用 frame 通過 net settings mod rgba bsp Qt3D教程(二)初步顯示3D的內容 前一篇很easy,全然就沒有牽涉到3D的內容,它僅僅是我們搭建3D應用的基本框架而已,而這一篇。我們將要利用它來初步地顯示3D

CSS3-loading動畫

sla 橢圓 clas gif 同時 沒有 .cn idt das CSS3-loading加載動畫 在線示例demo:http://liyunpei.xyz/loading.html 之前發了四篇,二十二個效果,今天再分享六個效果,總計二十八個效果。 二十三、效果二

QT學習筆記3 我的第一個程序

9.png har 中文 gets 有一個 setw 通過 坐標 關系 今天,學習搭建一個空項目,了解程序是如何運行的。 (1)新建一個空項目   1、在創建完空項目之後,項目中只有一個空的項目文件( .pro)        2、然後需要在項目文件(.pro)中添加:

QT學習筆記5 菜單欄、工具欄、窗口、對話框

let qlabel rman 運行 內存空間 介紹 edi left setw 本程序主要介紹了以下幾種常用控件的使用方法: (1)菜單欄、工具欄 (2)核心控件、狀態欄、浮動窗口 (3)模態窗口、非模態窗口 (4)標準對話框、文件對話框 代碼如下: mainwindow

QT學習筆記14 定時器類DTimer的使用

fin isa play htm number conn stat alt .cn 一、   在前面的學習筆記中,我們已經學習定時器事件http://www.cnblogs.com/blog-ccs/p/7445323.html   現在,我們學習QTimer定時器類,比較

QT學習筆記13 QT下的UDP通信

組播 create pan int cor 通過 width widget window 一、UDP通信   UDP通信沒有明確的服務器端和客戶端之分   TCP通信像是打電話(必須要接通才能通信),UDP通信像是寫信(不管能不能收到都發送出去)   首先需要QUdpSOc