Russian Qt Forum
Сентябрь 30, 2024, 16:31 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: [РЕШЕНО] Анимированный спрайт от QGraphicsItem  (Прочитано 6374 раз)
Hrundel
Гость
« : Июнь 19, 2013, 17:04 »

Всем привет,

задался целью написать анимированный спрайт наследуемый от QGraphicsItem. С простым виджетом получилось без проблем: Встроил таймер, переписал paintEvent и все заработало. Однако там есть конструктор и все такое. С QGraphicsItem до сих пор ни разу не работал - по сему даже представить не могу, какова логика при создании спрайта. Таймер вроде как нужен. Но как его туда вживить. Или его надо где-то снаружи оставить. И как там с  Pixmap работать? Возможно там использовать такие конструкции?

Код:
pixmap->fill(QColor("transparent"));
painter->drawPixmap(0, 0, 1024, 640, *spriteImage, x,y,1024,640);  

Буду рад всем советам, примерам и замечаниям для понимая логики работы  с QGraphicsItem.
Спасибо.
« Последнее редактирование: Июнь 21, 2013, 23:39 от Hrundel » Записан
Bepec
Гость
« Ответ #1 : Июнь 19, 2013, 17:36 »

Наследоваться от итема и делать что душе угодно в paintEvent.
Записан
Hrundel
Гость
« Ответ #2 : Июнь 19, 2013, 21:24 »

Да,  я , собственно, поэтому тему и открыл, что не все так просто.
Ладно конструктор там использовать можно, но так как QGraphicsItem наследуется не от QObject то присобачить таймер к нему не получается.
Метода paintEvent  у него тоже нет, есть только paint

Код:
paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*)

Опять как-то, не совсем стандартно.

В варианте с Qwidget  я реализовал это просто:

Код:
#include "animatedsprite.h"

AnimatedSprite::AnimatedSprite(QWidget *parent) :
    QWidget(parent), x(0), y(0)
{
    pixmap = new QPixmap(128,128);
    pixmap->fill(QColor("transparent"));
    spriteImage = new QPixmap(":/img/images/sprite2.png");
    painter = new QPainter(pixmap);
    label = new QLabel(this);
    label->setGeometry(0,0,128,128);
    label->show();

    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(nextSlide()));
    timer->start(30);
}

void AnimatedSprite::paintEvent(QPaintEvent *)
{
    pixmap->fill(QColor("transparent"));
    painter->drawPixmap(0, 0, 1024, 640, *spriteImage, x,y,1024,640);

    label->setPixmap(*pixmap);
}

void AnimatedSprite::nextSlide()
{
    if(x > 895)
    {
        x = 0;
        if(y > 512)
        {
            y = 0;
        }
        else y += 128;
    }
    else
    {
        if(x >= 512 && y >= 512)
        {
            x = 0;
            y = 0;
            //timer->stop();
        }
        x += 128;
    }
    this->update();
}

Но здесь так не получается. Нужен другой подход. А какой я не знаю.

Кстати, есть еще класс QGraphicsPixmapItem
Он, наверное, подходит еще лучше для спрайта. Но по своей архитектуре он такой же как и QGraphicsItem.
Записан
Bepec
Гость
« Ответ #3 : Июнь 19, 2013, 22:01 »

Что вы бред несёте. Он наследник QObject. QTimer в руки и погнали картинки отрисовывать, а не темы на форуме калякать Подмигивающий
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #4 : Июнь 19, 2013, 22:12 »

Что вы бред несёте. Он наследник QObject. QTimer в руки и погнали картинки отрисовывать, а не темы на форуме калякать Подмигивающий
Да ладно. Улыбающийся

Ладно конструктор там использовать можно, но так как QGraphicsItem наследуется не от QObject то присобачить таймер к нему не получается.
А QGraphicsObject наследуется.
Записан
Hrundel
Гость
« Ответ #5 : Июнь 19, 2013, 22:47 »

Что вы бред несёте. Он наследник QObject. QTimer в руки и погнали картинки отрисовывать, а не темы на форуме калякать Подмигивающий

Ну ладно, сегодня я уже винца выпил, а завтра продолжим Подмигивающий
Записан
Bepec
Гость
« Ответ #6 : Июнь 19, 2013, 23:27 »

А мож и ошибаюсь Улыбающийся Надо уточнить Веселый Завтра Веселый
Записан
Hrundel
Гость
« Ответ #7 : Июнь 20, 2013, 11:08 »

Ну, вот нашел всю иерархию классов можешь глянуть http://doc.qt.nokia.com/extras/qt43-class-chart.pdf

QGraphicsItem стоит отдельно но его некоторые потомки роднятся и с QObject тоже.
Но прямые потомки как QGraphicsPixmapItem - не роднятся

Так что Bepec учи матчасть и не калякай в форумах Веселый Подмигивающий

А если серьезно - идеи какие-нибудь есть?

Old, спасибо за наводку на QGraphicsObject. Буду разбираться
« Последнее редактирование: Июнь 20, 2013, 11:32 от Hrundel » Записан
Bepec
Гость
« Ответ #8 : Июнь 20, 2013, 12:15 »

Хей, с благодарностью приму данную информацию Улыбающийся
Записан
Hrundel
Гость
« Ответ #9 : Июнь 21, 2013, 23:38 »

Ок, написал!
В общем ситуация выглядит так:

1. Наследуемся от QGraphicsItem
2. Таймер должен быть с наружи
3. У наследника надо переписать
Код:
protected:void advance(int phase);
тогда его можно анимировать таймером не внедряя оный ему в тело.
4. advance ловиться не самим объектом а сценой, то есть выглядеть будет так:

Код:
    timer = new QTimer();
    connect(timer, SIGNAL(timeout()), &scene, SLOT(advance()));
    timer->start(30);

    PixmapItem* obj =  new PixmapItem();
    obj->setX(128);
    obj->setY(128);
    scene.addItem(obj);

Вывод: Таймер один ДЛЯ ВСЕХ АНМИРОВАННЫХ ЭЛЕМЕНТОВ СЦЕНЫ!!! Так что анимацию всех спрайтов необходимо делать на одинаковой частоте.

Всем спасибо!
« Последнее редактирование: Июнь 22, 2013, 10:16 от Hrundel » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.07 секунд. Запросов: 20.