PDA

View Full Version : multiple QPropertyAnimations after each other, how???



e1in9
1st August 2010, 15:58
Hi,

I have made a class (Block) that inherits from QGraphicsItem and QObject and therefore can be animated by QPropertyAnimation. Currently I have implemented that the Block-object moves & animates to the right by 20 position-units. (See function stepRight() below). This works when called one time. But my problem is, I can not get it to play multiple times after each other, e.g. in a loop.

For example when I call the function test() below it starts the first animation, and then immediately the others, while the first is not finished yet with playing. So... only the first animation is executed/played!

I want to be able to call stepRight() five times in a loop and that all the five animations get executed sequentially. Is there any sort of method for such thing, must I use other animation methods? Timers?



void Block::test() { // slot, called when pressed button
for (int i=0; i < 5; i++) {
stepRight();

if (!finished)
printf("anim not finished\n");
}
}

void Block::stepRight(){
if( !finished) return; // if I remove this only last animation is played
animatePosition(QPointF(pos().x(),pos().y()), QPointF(pos().x()+width, pos().y()));
setX(x() + width);
}

void Block::animatePosition(const QPointF& start, const QPointF& end){
anim = new QPropertyAnimation(this, "pos");
finished = false;
anim->setDuration(3000);
anim->setStartValue(start);
anim->setEndValue(end);

QObject::connect(anim, SIGNAL(finished()), this, SLOT(animationFinished()));

anim->start();
}

void Block::animationFinished() {
// This slot is called when animation ends

printf("anim finished\n");
finished = true;
}

Lykurg
1st August 2010, 17:45
Have a look at QSequentialAnimationGroup.

e1in9
2nd August 2010, 01:13
Thanks... btw maybe it was a bit of a stupid question.

However now I have another issue/question regarding this QSequentialAnimationGroup thing... I want to adjust the x value after the block (a QGraphicsItem as said) has moved to the right. Just to keep track of it and for interaction between classes.

But if I adjust the x value as in the example below the animation is not longer displayed correctly.
The block is then first displayed on it's FINAL position, and then moved back to it's original position for the animation to start. But the block should not be first displayed on it's final position.



Block * block1 = new Block(40,20,20); // params: x pos, y pos, width
// using setPos(x,y) in constructor

// declaration of 2 qpropertyanimations for block1
QPropertyAnimation * anim4 = new QPropertyAnimation(block1, "pos");
anim4->setDuration(2000);
anim4->setStartValue(QPointF(40,20));
anim4->setEndValue(QPointF(60,20));
QPropertyAnimation * anim5 = new QPropertyAnimation(block1, "pos");
anim5->setDuration(2000);
anim5->setStartValue(QPointF(60,20));
anim5->setEndValue(QPointF(80,20));

QSequentialAnimationGroup * group = new QSequentialAnimationGroup;
printf("x: %f\n", block1->x()); // says 40
group->addAnimation(anim4);
block1->setX(block1->x()+20);
printf("x: %f\n", block1->x()); // says 60
group->addAnimation(anim5);
block1->setX(block1->x()+20);
printf("x: %f\n", block1->x()); // says 80
group->start();


I tried to change the order of the setX(..) commands but it does not help :confused:
Why is it first displayed on position 80? Any ideas?
If I do NOT add the setX(..) command. the animation works properly, but then the x() value of block1 remains 40.