Название: Как реализовать анимацию gif-картинки на сцене? Отправлено: Greep от Февраль 20, 2010, 21:54 Есть класс, наследуемый от QGraphicsItem:
Код: class Image : public QGraphicsItem Код: Image::Image(const QString &fileName) Этот код отображает на сцену только первый (если я не ошибаюсь) кадр из гифки. Собственно сабж: как сделать анимацию? ПС: пробовал что-то сделать через QMovie и QImageReader - ничего не вышло. ППС: неужели QMovie можно использовать только в связке с QLabel? Название: Re: Как реализовать анимацию gif-картинки на сцене? Отправлено: SABROG от Февраль 20, 2010, 23:25 ППС: неужели QMovie можно использовать только в связке с QLabel? Плохо читал документацию. Используй сигнал void QMovie::frameChanged ( int frameNumber ) [signal], в слоте вызывай update(), в paint() вызывай QPixmap QMovie::currentPixmap () const Название: Re: Как реализовать анимацию gif-картинки на сц Отправлено: Greep от Февраль 21, 2010, 01:22 Спасибо за совет. Но при попытке следовать этому совету появилась необходимость добавить слот в класс Image, но это оказалось не так просто. QGraphicsItem не является потомком QObject, поэтому просто приписав макрос Q_OBJECT сигналов\слотов не получить. Если сделать множественное наследование от QObject и QGraphicsItem, то компилятор ругается на то, что методы класса QGraphicsItem недоступны из класса Image.
Цитировать ~/mainwindow.cpp:88: error: 'QGraphicsItem' is not an accessible base of 'Image' Название: Re: Как реализовать анимацию gif-картинки на сцене? Отправлено: SABROG от Февраль 21, 2010, 02:08 А я и не писал, что нужно добавлять слоты в QGraphicsItem. Добавлять нужно в класс, который управляет всей сценой и QMovie привязывать к конкретному итему, а уж как это реализовать думай сам.
Название: Re: Как реализовать анимацию gif-картинки на сц Отправлено: Greep от Февраль 21, 2010, 02:12 А я и не писал, что нужно добавлять слоты в QGraphicsItem. Добавлять нужно в класс, который управляет всей сценой и QMovie привязывать к конкретному итему, а уж как это реализовать думай сам. т.е. при каждой смене кадра в анимации нужно будет обновлять всю сцену? О_оА если на сцене сотня gif-ок, в которых кадры меняются с интервалом 0 мс? Upd: оказывается у сцены есть слот update(QRectF); Upd2: но это ничего не меняет :( Upd3: кое-что получилось, изменённый код: Код: class Image : public QGraphicsItem Код: Image::Image(const QString &fileName) ну и соответственно при создании объекта класса Image делается коннект: Код: Image *img = new Image(fileName); Название: Re: Как реализовать анимацию gif-картинки на сц Отправлено: SABROG от Февраль 21, 2010, 14:59 Код: connect(img->getMovie(), SIGNAL(frameChanged(int)), scene, SLOT(update())); Обновлять сцену целиком конечно оверхед. У каждого QGraphicsItem'a есть собственный метод update(). Просто нужно ловить сигналы frameChanged() от каждого экземпляра QMovie в одном слоте. Можно использовать для этого класс QSignalMapper, из которого получать сигнал с параметрами, например, указатель на QMovie и QGraphicsItem который нужно обновить. Название: Re: Как реализовать анимацию gif-картинки на сц Отправлено: Greep от Февраль 21, 2010, 15:28 В QSignalMapper нельзя передать указатель на класс Image т.к. он не является потомком ни QWidget-a ни QObject-a...
ПС: если я правильно понял семантику использования QSignalMapper-а upd: я думаю оптимальным было бы сделать слот update() в классе Image, но как я ни пытался, у меня не получается сделать двойное наследование от QObject-a и QGraphicsItem-a Название: Re: Как реализовать анимацию gif-картинки на сцене? Отправлено: SABROG от Февраль 21, 2010, 17:04 Зато можно присвоить ID
void QSignalMapper::setMapping ( QObject * sender, int id ) В int можно запихнуть как индекс какого-нибудь списка, так и сам указатель, просто reinterpret_cast<>() придется вызывать. Или idшник можно впихнуть в QGraphicsItem: void QGraphicsItem::setData ( int key, const QVariant & value ) Потом пробегаться по всем итемам на сцене и искать нужный ID: QList<QGraphicsItem *> QGraphicsScene::items () const Название: Re: Как реализовать анимацию gif-картинки на сц Отправлено: Greep от Февраль 21, 2010, 18:52 Кое что получилось:
Код: class MainWindow : public QMainWindow Код: MainWindow::MainWindow(QWidget *parent) Блин, ну не может же быть всё так сложно >_< Название: Re: Как реализовать анимацию gif-картинки на сц Отправлено: SABROG от Февраль 22, 2010, 00:39 Блин, ну не может же быть всё так сложно >_< Ну попробуй в QGraphicsPixmapItem впихни .gif, правда я не думаю, что будет анимация. Можно еще попробовать QLabel добавить на сцену, только имхо это оверхед. Название: Re: Как реализовать анимацию gif-картинки на сцене? Отправлено: Greep от Февраль 22, 2010, 00:50 Как ни крути оверхед получается.
Спасибо за помощь =) Название: Re: Как реализовать анимацию gif-картинки на сцене? Отправлено: SABROG от Февраль 22, 2010, 23:15 Как вариант можно попробовать замутить через QGraphicsEffect (http://qt.nokia.com/doc/4.6/qgraphicseffect.html)
Придется его унаследовать и сделать практически тоже самое что и в QGraphicsItem::paint(). Зато здесь есть слот update() к которому можно подвязать сигнал frameChanged(). В общем-то в этом случае можно аггрегировать QMovie в QGraphicsEffect, таким образом у тебя весь функционал будет в одном классе и каждый экземпляр QGraphicsEffect будет содержать свою анимацию, которую можно включить и выключить в любое время, соответственно уже можно будет использовать голый QGraphicsItem или любой другой класс на его базе. Например вывод прозрачной анимации на какой-нибудь QWidget на сцене. Название: Re: Как реализовать анимацию gif-картинки на сцене? Отправлено: BiTOk от Май 08, 2010, 12:29 Тоже столкнулся с этой проблемой. Попробовал реализовать так:
QMovie проигрывает gifanim. frameChanged соединил со слотом, в котором написал Код: worker->setPixmap(pixmap); Название: Re: Как реализовать анимацию gif-картинки на сцене? Отправлено: p166 от Май 20, 2010, 16:00 Мне кажется такие вещи много проще делать через QML.
QML AnimatedImage Element Reference Properties currentFrame : int frameCount : int paused : bool playing : bool Detailed Description This item provides for playing animations stored as images containing a series of frames, such as GIF files. The full list of supported formats can be determined with QMovie::supportedFormats(). Item { width: anim.width; height: anim.height+8 AnimatedImage { id: anim; source: "pics/games-anim.gif" } Rectangle { color: "red"; width: 4; height: 8; y: anim.height x: (anim.width-width)*anim.currentFrame/(anim.frameCount-1) } } |