Отображать статичные изображения в 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();
Обратите внимание на две особенности:
QLabel
передается указатель на объект типа QMovie
;start()
.Создадим проект с применением QMovie
. Типичное использование GIF-анимации заключается в создании индикаторов ожидания:
Заголовочный файл 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
Спасибо за полезный комментарий.
Здравствуйте, Jorjio774. Чего именно Вы хотите добиться от использования QtConcurrent? Обычно имеется четкий момент старта (run()) и финиша (т.е. получения результата - result()). Тогда stop() для анимации можно вызывать перед run(), а start() - после result() или waitForFinished(). Усложнять и внедрять прямые зависимости от QMovie здесь не стоит. Зато уместно задействовать RAII.
rrrfer
Надо сказать, что эта анимация не всегда подходит. На работе мы писали игрушки и там была тайловая анимация - или как там называется когда кадры лежат в здоровенном png файле, а в еще одном файле описаны их расположения.
Когда начал писать для себя на Qt - подумал, что должен быть стандартный способ сделать такую анимацию и не стал заниматься велосипедостроением, взял QMovie и положил на QLabel. Ну а потом опубликовал первую игрушку под Android, которая на моем телефоне отлично смотрелась. Тут начались возгласы юзеров о хреновом качестве картинки (хотя художник рисовал в векторе, а потом перегонял в gif). В конце концов пришлось мне написать велосипед для тайловой анимации, хотя вроде бы в QML есть что-то готовое для таких дел.