QGraphicsRectItem::rect is not updated after item is moved

1.5k views Asked by At

I am having a rectangle item with a proper transformation, shown on the scene. It is also made movable.

rectItem = new QGraphicsRectItem();
rectItem->setRect(someRect);

scene->addItem(rectItem);
rectItem->setTransform(homography);
rectItem->setFlag(ItemIsMovable);

Problem is, whenever it is moved with interaction, by amount of dx, its rect property doesnt change. End of movement is captured in mouse release event, and a signal is fired there - connected to this slot:

finalRect = rectItem->rect(); // this doesnt change, however item is properly moved to another spot on the scene

I was expecting: finalRect should move by homography.inverted().map(dx)

Is something wrong with my assumption ? Or is there a bug ?

2

There are 2 answers

0
TheDarkKnight On BEST ANSWER

The rect defined in QGraphicsRectItem is actually the boundingRect of the item, which is in local coordinates. If this changes, the item will change its size.

As the item is not parented, setting its coordinates and adding it to the scene will appear to set its position by changing its rect: -

QRectF rect(10, 10, 20, 20);
rectItem = new QGraphicsRectItem();
rectItem->setRect(someRect);
scene->addItem(rectItem);

This rect is being set to (x, y) at (10,10) with width and height of 20. With no parent, adding it to the scene will not only define the rect's local coordinates as (10, 10, 20, 20), but it will be positioned with its top left at (10,10) and so appears that setRect defines its position.

What you should do is think about the size of the rect and where you want it positioned in local coordinates. For example, you may want the position to be around its centre, rather than the top left. In this case you can do the following: -

QRectF rect(-10, -10, 20, 20);
rectItem = new QGraphicsRectItem();
rectItem->setRect(someRect);
scene->addItem(rectItem);

Now we've defined the local coordinates of the rect and added it to the scene, we can position it where we want: -

rectItem->setPos(15, 15);

The rect is now position with its centre at (15, 15).

In order to get the rect's position in the scene, you can call its pos() function, but note that the returned coordinates are relative to the item's parent. With no parent, the item's scene coordinates are returned.

If an item is parented, you can either translate the local pos() coordinates to the scene, or simply call scenePos()

1
Jablonski On

It is normal for rect. Use pos() or scenePos() instead.

qDebug() << rectItem->rect() << rectItem->pos() << rectItem->scenePos();

rectItem->rect() will be same until you call setRect again but scenePos() will change accordingly to your scene.