I'm trying do some 3D animation in GraphicsScene, for example, to rotate pictures in GraphicsScene (using class, subclassed from qPixmapItem
and QObject
, if it matters) with Animation framework.
Everything works fine, until i want to rotate pictures around vertical axis.
There is no way doing so via item.rotate(), so i'm using QTranform
.
The problem is that doing so does not animate anything at all. What am i doing wrong?
P.S. I do not want use OpenGl for this.
Here is the way i'm doing it. This way works for animating simpler properties like pos
, rotation(via rotation
, setRotation
)
My code :
// hybrid graphicsSceneItem, supporting animation
class ScenePixmap : public QObject, public QGraphicsPixmapItem
{
Q_OBJECT
Q_PROPERTY(QTransform transform READ transform WRITE setTransform)
public:
ScenePixmap(const QPixmap &pixmap, QObject* parent = NULL, QGraphicsItem* parentItem = NULL):
QObject(parent),
QGraphicsPixmapItem(pixmap, parentItem)
{}
};
Here is how I setup scene and animation:
//setup scene
//Unrelated stuff, loading pictures, etc.
scene = new QGraphicsScene(this);
foreach(const QPixmap& image, images)
{
ScenePixmap* item = new ScenePixmap(image);
item->moveBy(70*i, 0);
i++;
this->images.append(item);
scene->addItem(item);
}
}
ui->graphicsView->setBackgroundBrush(QBrush(Qt::black, Qt::SolidPattern));
ui->graphicsView->setScene(scene);
//setup animation
QTransform getTransform()
{
QTransform transform;
transform.rotate(-30, Qt::ZAxis);//also tried transform = transform.rotate(...)
return transform;
}
QAbstractAnimation* SetupRotationAnimation(ScenePixmap* pixmapItem)
{
QPropertyAnimation* animation = new QPropertyAnimation(pixmapItem, "transform");
animation->setDuration(1400);
animation->setStartValue( pixmapItem->transform());
animation->setEndValue(getTransform());//here i tried to multiply with default transform , this does not work either
return animation;
}
here is the way i start animation:
void MainWindow::keyPressEvent ( QKeyEvent * event )
{
if((event->modifiers() & Qt::ControlModifier))
{
QAnimationGroup* groupAnimation = new QParallelAnimationGroup();
foreach(ScenePixmap* image, images)
{
groupAnimation->addAnimation( SetupRotationAnimation(image));
}
groupAnimation->start(QAbstractAnimation::DeleteWhenStopped);
}
}
EDIT[Solved] thx to Darko Maksimovic:
Here is the code that worked out for me:
QGraphicsRotation* getGraphicRotation()
{
QGraphicsRotation* transform = new QGraphicsRotation(this);
transform->setAxis(Qt::YAxis);
return transform;
}
QAbstractAnimation* SetupRotationAnimation(ScenePixmap* pixmapItem)
{
QGraphicsRotation* rotation = getGraphicRotation();
QPropertyAnimation* animation = new QPropertyAnimation(rotation, "angle");
animation->setDuration(1400);
animation->setStartValue( 0);
animation->setEndValue(45);
pixmapItem->setTransformOriginPoint(pixmapItem->boundingRect().center());
QList<QGraphicsTransform*> transfromations = pixmapItem->transformations();
transfromations.append(rotation);
pixmapItem->setTransformations(transfromations);
return animation;
}
I see you use QTransform. If you want only one rotation, and simple rotation that is, it is better that you use setRotation [don't forget about setTransformOriginPoint].
If you, however, want to remember many rotations, around different transform points for example, then you should use QGraphicsTransform, i.e. its specialised derived class, QGraphicsRotation, which you apply by calling setTransformations on a graphics object (you should first fetch the existing transformations by calling o.transformations(), append to this, then call setTransformations; if you keep the pointer to the added transformation you can also change it later directly).
From the code you posted I can't see where your error is coming from, but by using specialised functions you can avoid some of frequent problems.
P.S. I also see you didn't use prepareGeometryChange in the code you posted, so please be advised that this is necessary when transforming objects.