IT Notes

QMovie: GIF-анимация в Qt

Отображать статичные изображения в Qt-приложениях очень легко. Для этого подходит QLabel:

QPixmap pix( "/path/to/file" );
label->setPixmap( pix ); // label имеет тип QLabel*

Вывести GIF-анимацию не намного сложнее. В этом нам поможет QMovie и все тот же QLabel:

QMovie movie( "/path/to/file" );
label->setMovie( &movie ); // label имеет тип QLabel*
movie.start();

Обратите внимание на две особенности:

  1. В QLabel передается указатель на объект типа QMovie;
  2. GIF-анимация запускается явно вызовом start().

Создадим проект с применением QMovie. Типичное использование GIF-анимации заключается в создании индикаторов ожидания:

qt-gif-animation-demo-widget

Заголовочный файл gifanimationdemowidget.h:

#ifndef GIFANIMATIONDEMOWIDGET_H
#define GIFANIMATIONDEMOWIDGET_H

#include <QWidget>
#include <QMovie>

namespace Ui {
class GIFAnimationDemoWidget;
}

class GIFAnimationDemoWidget : public QWidget {
    Q_OBJECT

public:
    explicit GIFAnimationDemoWidget( QWidget* parent = 0 );
    ~GIFAnimationDemoWidget();

private:
    Ui::GIFAnimationDemoWidget* ui;

    QMovie m_movie;
};

#endif // GIFANIMATIONDEMOWIDGET_H

Файл реализации gifanimationdemowidget.cpp:

#include "gifanimationdemowidget.h"
#include "ui_gifanimationdemowidget.h"

GIFAnimationDemoWidget::GIFAnimationDemoWidget( QWidget* parent ) :
    QWidget( parent ), ui( new Ui::GIFAnimationDemoWidget ), m_movie( ":/loading.gif" ) {
    ui->setupUi( this );

    ui->lbMovie->setMovie( &m_movie );

    connect( ui->bnStart, SIGNAL( clicked( bool ) ), &m_movie, SLOT( start() ) );
    connect( ui->bnStop, SIGNAL( clicked( bool ) ), &m_movie, SLOT( stop() ) );
}

GIFAnimationDemoWidget::~GIFAnimationDemoWidget() {
    delete ui;
}

Изображение loading.gif помещено в ресурсы приложения:

<RCC>
    <qresource prefix="/">
        <file>loading.gif</file>
    </qresource>
</RCC>

Запуск и остановка анимации привязаны к нажатию кнопок Start и Stop через систему сигналов-слотов.

Исходники

 Скачать пример использования GIF-анимации в Qt на основе QMovie

Похожие публикации

Комментарии

Надо сказать, что эта анимация не всегда подходит. На работе мы писали игрушки и там была тайловая анимация - или как там называется когда кадры лежат в здоровенном png файле, а в еще одном файле описаны их расположения.

Когда начал писать для себя на Qt - подумал, что должен быть стандартный способ сделать такую анимацию и не стал заниматься велосипедостроением, взял QMovie и положил на QLabel. Ну а потом опубликовал первую игрушку под Android, которая на моем телефоне отлично смотрелась. Тут начались возгласы юзеров о хреновом качестве картинки (хотя художник рисовал в векторе, а потом перегонял в gif). В конце концов пришлось мне написать велосипед для тайловой анимации, хотя вроде бы в QML есть что-то готовое для таких дел.

Спасибо за полезный комментарий.

Здравствуйте, Jorjio774. Чего именно Вы хотите добиться от использования QtConcurrent? Обычно имеется четкий момент старта (run()) и финиша (т.е. получения результата - result()). Тогда stop() для анимации можно вызывать перед run(), а start() - после result() или waitForFinished(). Усложнять и внедрять прямые зависимости от QMovie здесь не стоит. Зато уместно задействовать RAII.