Important: Please read the Qt Code of Conduct -

QGraphicsItem::setTransformOriginPoint(x,y) not working as expected

  • I'm using a QGraphicsItemAnimation to animate the rotation of a QGraphicsPixmapItem. By default, the QGraphicsPixmapItem is rotated about local (0, 0), ie the top left corner of the image. For my purposes, I need it to rotate about a different point, so I tried using QGraphicsItem::setTransformOriginPoint(x, y), but no matter what values I passed, the image still rotated about local (0, 0). Code snippet follows.


    class Character : public QGraphicsItem {

    QRectF boundingRect() const;
    void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*);

    QGraphicsPixmapItem *torso, *head, *upper_arm, *lower_arm, *hand, *thigh, *calf, *foot;

    QTimeLine *timeLine;

    Character::Character() {
    torso = new QGraphicsPixmapItem(QPixmap("img/torso.png"), this);
    thigh = new QGraphicsPixmapItem(QPixmap("img/thigh.png"), torso);

    torso->setPos(-35, -95);
    thigh->setPos(8, 144);

    thigh->setTransformOriginPoint(32, 14);

    timeLine = new QTimeLine;
    timeLine->setUpdateInterval(1000 / 25);

    QGraphicsItemAnimation thigh_anim = new QGraphicsItemAnimation;
    thigh_anim->setRotationAt(0.00, -64.52+90);
    lots of rotation points excluded for brevity */
    thigh_anim->setRotationAt(1.00, -64.52+90);



    Any and all help is greatly appreciated.

  • try something like this ..

    thigh->setTransform(QTransform().translate(32,14).rotate(degrees).translate(-32, -14), true);

    basic idea is you move the origin, rotate and move the origin back.

    as per docs, setTransformOriginPoint should have worked, but I'm using the code snip I posted in an existing project and it works fine

  • that works if and only if you have strict control over the execution order, thus the massive one-liner. unfortunately, in this case, since i'm doing the rotating with a QGraphicsItemAnimation, that isn't the case. i can't take the risk of it rendering one of the offset locations. that would cause cause really bad flickering. I'm wondering whether this is worth a bug report, or if i'm simply reading the spec wrong and what i'm trying to do isn't currently possible.

  • I am using the approach I mentioned, and I've seen smooth animation up to 25-30fps, image size was up to 400x800

  • ok ... i'm going for full screen animation ... but, out of curiosity, what animation mechanism are you using? if you wouldn't mind posting a more complete drawing example, i'd love to see it. i based my approach off of the Drag and Drop Robot example [ ].

  • let me see if I can put up something over the weekend here, also one question, how big is the item in terms of pixel size (WxH), that you are trying to rotate with an offset origin? and what is the kind of fps you are trying to achieve?

  • A side note. QGraphicsItemAnimation class seems to be deprecated already, unfortunately. The various classes of Animation Framework won't let you change e.g. the update interval, so you're stuck with the default 60 per sec or so. That means a maximum of 60 pixel-by-pixel transition of an image on screen per second. For most cases that is enough though, I guess. Or is there some nice trick I've missed?

  • @Johannes: thanks for pointing out that QGraphicsItemAnimation is deprecated. I'll look into the new Animation Framework.

  • i posted a reply and it vanished, some refresh issue at my end i guess, posting again

    fps at 60 in Animation fw is not guaranteed, if the frames are complex to calculate and render, you get much lesser fps.

    With QTimeLine you can have custom fps using updateInterval and duration, but if that fps can't be achieved, you tend to loose frames in between -- resulting in jerks in animation

  • QGraphicsItem::setTransformOriginPoint(x, y) is working perfectly for me with smooth 60fps animation in a game on Symbian (N8). I'm not using the animation class on top though - I'm doing the rotation myself in the game loop.

Log in to reply