PDA

View Full Version : How to make an QGraphicsObject animation?



luisvaldes88
25th August 2011, 02:04
Hi,

I am new on this forum.

I am making an application. it consits of:
1 QGraphicsView
1 QGraphicsScene
1 QGraphicsObject derived class.

the derived class has emits a signal when clicked, an the application goes to another state, but before it goes, it has to first animate the QGrapchisObject derived class,
that is inside the scene.

I have a list of images, and I have to animate the sequence without erasing the first image.

I think about creating a class to do the work.


#ifndef GRAPHIC_H
#define GRAPHIC_H

#include <QGraphicsObject>
#include <QtCore>

class Graphic : public QGraphicsObject
{
Q_OBJECT
protected:
QPixmap image;

public:
enum {Type = GraphicType};
int type() const { return Type;}

Graphic(const QPixmap &pix,
const QPointF & point = QPointF(),
QGraphicsItem *parent = 0);

signals:
void clicked();
};

#endif // GRAPHIC_H




#ifndef ANIMATIONHELPER_H
#define ANIMATIONHELPER_H

#include <QObject>

class Graphic;
class QGraphicsScene;

class AnimationHelper : public QObject
{
Q_OBJECT
QList<Graphic *> m_sequence;
QGraphicsScene *m_scene;

public:
explicit AnimationHelper(QObject *parent = 0);
explicit AnimationHelper(int pause, int duration, QGraphicsScene *scene, QObject *parent = 0);
int m_pause;
int m_duration;
bool empty;
public:
AnimationHelper(QGraphicsScene *scene, QObject *parent = 0);
void addGraphic(Graphic * myG);

public slots:
void onGraphicClicked();

signals:
void clicked();

};

#endif // ANIMATIONHELPER_H


//implementation

MyAnimationHelper::onMyGraphicsClicked()
{
QSequentialAnimationGroup *animationGroup = new QSequentialAnimationGroup(this);
animationGroup->addPause(m_pause;);
foreach(Graphics *g, m_sequence)
{
scene->addItem(g);
QPropertyAnimation *animation = new QPropertyAnimation(g, "opacity", this);
animation->setDuration(m_duration;);
animation->setStartValue(qreal(0));
animation->setEndValue(qreal(1));
animationGroup->addAnimation(animation);
}
animationGroup->start(QAbstractAnimation::DeleteWhenStopped);

emit clicked();
}

#include <QSequentialAnimationGroup>
#include <QPropertyAnimation>
#include "animationhelper.h"
#include "graphic.h"

AnimationHelper::AnimationHelper(QObject *parent) :
QObject(parent)
{
}

AnimationHelper::AnimationHelper(int pause, int duration, QGraphicsScene *scene, QObject *parent) :
QObject(parent), m_pause(pause), m_duration(duration), empty(true)
{
m_scene = scene;
}

void AnimationHelper::addGraphic(Graphic * myG)
{
if(empty)
{
empty = false;
myG->setProperty("opacity", 1);
m_scene->addItem(myG);
connect(myG, SIGNAL(clicked()), this, SLOT(onGraphicClicked()));
}
else
{
myG->setProperty("opacity", 0);
m_scene->addItem(myG);
m_sequence.append(myG);
}
}

void AnimationHelper::onGraphicClicked()
{
QSequentialAnimationGroup *animationGroup = new QSequentialAnimationGroup(this);
animationGroup->addPause(m_pause);
foreach(Graphic *g, m_sequence)
{
QPropertyAnimation *animation = new QPropertyAnimation(g, "opacity", this);
animation->setDuration(m_duration);
animation->setStartValue(qreal(0));
animation->setEndValue(qreal(1));
animationGroup->addAnimation(animation);
}
animationGroup->start(QAbstractAnimation::DeleteWhenStopped);
emit clicked();
}


I think you could get the idea, this actually works, but the main thing is that I dont know if there is a better way of making the animation.

Best Regards.

wysota
25th August 2011, 08:54
Looks ok to me. You probably could use the state machine as well but only if it fits your other goals.

luisvaldes88
25th August 2011, 19:01
Hi,

I am new on this forum.

I am making an application. it consits of:
1 QGraphicsView
1 QGraphicsScene
1 QGraphicsObject derived class.

the derived class has emits a signal when clicked, an the application goes to another state, but before it goes, it has to first animate the QGrapchisObject derived class,
that is inside the scene.

I have a list of images, and I have to animate the sequence without erasing the first image.

I think about creating a class to do the work.


#ifndef GRAPHIC_H
#define GRAPHIC_H

#include <QGraphicsObject>
#include <QtCore>

class Graphic : public QGraphicsObject
{
Q_OBJECT
protected:
QPixmap image;

public:
enum {Type = GraphicType};
int type() const { return Type;}

Graphic(const QPixmap &pix,
const QPointF & point = QPointF(),
QGraphicsItem *parent = 0);

signals:
void clicked();
};

#endif // GRAPHIC_H




#ifndef ANIMATIONHELPER_H
#define ANIMATIONHELPER_H

#include <QObject>

class Graphic;
class QGraphicsScene;

class AnimationHelper : public QObject
{
Q_OBJECT
QList<Graphic *> m_sequence;
QGraphicsScene *m_scene;

public:
explicit AnimationHelper(QObject *parent = 0);
explicit AnimationHelper(int pause, int duration, QGraphicsScene *scene, QObject *parent = 0);
int m_pause;
int m_duration;
bool empty;
public:
AnimationHelper(QGraphicsScene *scene, QObject *parent = 0);
void addGraphic(Graphic * myG);

public slots:
void onGraphicClicked();

signals:
void clicked();

};

#endif // ANIMATIONHELPER_H


//implementation

MyAnimationHelper::onMyGraphicsClicked()
{
QSequentialAnimationGroup *animationGroup = new QSequentialAnimationGroup(this);
animationGroup->addPause(m_pause;);
foreach(Graphics *g, m_sequence)
{
scene->addItem(g);
QPropertyAnimation *animation = new QPropertyAnimation(g, "opacity", this);
animation->setDuration(m_duration;);
animation->setStartValue(qreal(0));
animation->setEndValue(qreal(1));
animationGroup->addAnimation(animation);
}
animationGroup->start(QAbstractAnimation::DeleteWhenStopped);

emit clicked();
}

#include <QSequentialAnimationGroup>
#include <QPropertyAnimation>
#include "animationhelper.h"
#include "graphic.h"

AnimationHelper::AnimationHelper(QObject *parent) :
QObject(parent)
{
}

AnimationHelper::AnimationHelper(int pause, int duration, QGraphicsScene *scene, QObject *parent) :
QObject(parent), m_pause(pause), m_duration(duration), empty(true)
{
m_scene = scene;
}

void AnimationHelper::addGraphic(Graphic * myG)
{
if(empty)
{
empty = false;
myG->setProperty("opacity", 1);
m_scene->addItem(myG);
connect(myG, SIGNAL(clicked()), this, SLOT(onGraphicClicked()));
}
else
{
myG->setProperty("opacity", 0);
m_scene->addItem(myG);
m_sequence.append(myG);
}
}

void AnimationHelper::onGraphicClicked()
{
QSequentialAnimationGroup *animationGroup = new QSequentialAnimationGroup(this);
animationGroup->addPause(m_pause);
foreach(Graphic *g, m_sequence)
{
QPropertyAnimation *animation = new QPropertyAnimation(g, "opacity", this);
animation->setDuration(m_duration);
animation->setStartValue(qreal(0));
animation->setEndValue(qreal(1));
animationGroup->addAnimation(animation);
}
animationGroup->start(QAbstractAnimation::DeleteWhenStopped);
emit clicked();
}


I think you could get the idea, this actually works, but the main thing is that I dont know if there is a better way of making the animation.

Best Regards.

Hi!

Thank you for your answer!
I am going to continue with my plan!
I am using the state machine to start and stop diferent animations at the same time.