PDA

View Full Version : rotation of an animated QGraphicsItem



darksaga
6th September 2007, 13:21
hi there,

i've subclassed a QGraphicsItem to create a rotating & clickable icon for a QGraphicsScene,

rotation works fine, using QTimeLine & QGraphicsItemAnimation,

the problem that I'm facing now is that my item rotates around the coordinates 0/0,

how do I tell my item to rotate around its center: _with/2 / _height/2?

regards

ps: here's the code:


#ifndef ANIMATEICON_H
#define ANIMATEICON_H

#include <QObject>
#include <QGraphicsItem>
#include <QRectF>
#include <QPainter>
#include <QStyleOptionGraphicsItem>
#include <QWidget>
#include <QTimeLine>
#include <QGraphicsItemAnimation>

class AnimateIcon : public QObject, public QGraphicsItem
{
Q_OBJECT

public:
AnimateIcon(QGraphicsItem *parent = 0, int width = 48, int height = 48) : QGraphicsItem(parent){
_width = width;
_height = height;
_animation = new QGraphicsItemAnimation(this);
_timeLine = new QTimeLine(10000, this);

_animation->setItem(this);
_animation->setTimeLine(_timeLine);
for (int i = 0; i <= 360; i+=18)
_animation->setRotationAt(i/360.0, i);

_timeLine->setCurveShape(QTimeLine::LinearCurve);
_timeLine->setLoopCount(0);
_timeLine->start();

}
~AnimateIcon(void){}
QRectF boundingRect(void) const{
return QRectF(0, 0, _width, _height);
}
void paint(QPainter *painter, const QStyleOptionGraphicsItem * option, QWidget *widget = 0){
painter->drawPixmap(0, 0, _width, _height,QPixmap(":/icons/action.png"));
}

private:
int _width;
int _height;
QGraphicsItemAnimation *_animation;
QTimeLine *_timeLine;
};
#endif

wysota
6th September 2007, 14:10
Make its bounding rect QRect(-_width/2, -_height/2, _width, _height) and draw it accordingly. Simply speaking make 0,0 the middle of the item, not the top left corner.

darksaga
6th September 2007, 14:20
Make its bounding rect QRect(-_width/2, -_height/2, _width, _height) and draw it accordingly. Simply speaking make 0,0 the middle of the item, not the top left corner.

already thought about doing it this way,

but I thought, that there was some kind of function hidden inside the documentation I didn't find, something like setRotationAnchor()/setRotationCenter()

anyway, thx for your suggestion ;)

wysota
6th September 2007, 15:32
No, there isn't. A matrix rotation is always around the origin.

Bitto
6th September 2007, 21:43
To rotate around an arbitrary point (x, y), or (width/2, height/2) in your case, do this:



item->setTransform(QTransform().translate(x, y).rotate(a).translate(-x, -y));


To scale around an arbitrary point (x, y), or (width/2, height/2) in your case, do this:



item->setTransform(QTransform().translate(x, y).scale(sx, sy).translate(-x, -y));


I guess you see the pattern ;-).

wysota
7th September 2007, 07:40
I guess it's simpler to just move the origin ;)

Bitto
8th September 2007, 10:13
That depends on the item - sometimes it's easier to replace one line than to rewrite all your coordinates ;-).

momesana
8th September 2007, 11:49
what about QGraphicsSvgItem. It already implements boundingRect() which returns 0,0 as Point of origin for one Item I'm testing here. Can I also handle that doing a transformation? Redefining boundingRect seemingly isn't an option here ...

Thanx in advance

wysota
8th September 2007, 11:55
That depends on the item - sometimes it's easier to replace one line than to rewrite all your coordinates ;-).

You can always do the translation in the item's paint routine. Also a single line ;)

Bitto
9th September 2007, 08:11
momesana, you can just use the translate-rotate-translate trick from above, it works for any item and you don't have to modify it / subclass it / change its bounding rect or painting.

wysota, you'd have to translate the bounding rect, the shape, and the painter inside the paint() function. otherwise you'd get painting and collision artifacts.