PDA

View Full Version : How does QGraphicsItem::prepareGeometryChange() work?



wayfaerer
22nd March 2012, 20:55
I'm not having a problem with prepareGeometryChange(), I just wish I understood how it works. I tried looking at the source, but it wasn't very helpful for me. According to the docs it "Prepares the item for a geometry change. Call this function before changing the bounding rect of an item to keep QGraphicsScene's index up to date. prepareGeometryChange() will call update() if this is necessary."

Does "before" mean *right* before? Any time before? Does this mean I don't need to call update()?

Here is an example of where it becomes confusing: Say I have a QGraphicsItem subclass whose boundingRect() function returns a rectangle that is a static class member. If I want update the static rectangle, do I have to call prepareGeometryChange() on every instance of the class, update the static rectangle, and then call update() on every instance?

Spitfire
23rd March 2012, 16:37
I would say yes.
Even though you've changed single rectangle, bounding rectangle for every item has changed.
So every item that will have different bounding rect should call prepareGeometryChange().

As to why you should do that, it's because scene may need to redraw some other items to avoid artifacts.
You should do it before changing the rectangle but rectangle should be changed before flow control goes back to event loop after calling prepareGeometryChange().
And there should be no need to call update() as scene should do it for you.

wayfaerer
23rd March 2012, 18:09
What I don't understand is how the scene knows the bounding rectangle has changed, since there is no setter for the bounding rect, only a getter. Does this mean that after you call prepareGeometryChange() the scene begins polling for changes, by calling QGraphicsItem::boundingRect() and comparing that one with what it has stored?

I think something you said might be the answer, if you could confirm it:

"...rectangle should be changed before flow control goes back to event loop after calling prepareGeometryChange()"

Does this mean that QGraphicsScene only polls for a change right before control goes back to the event loop (and of course, only if prepareGeometryChange() has been called)?

wysota
25th March 2012, 20:01
Does "before" mean *right* before? Any time before?
Any time after you know the rect is going to change and before you relinquish control of the flow to the event loop.


Does this mean I don't need to call update()?
Correct.


Say I have a QGraphicsItem subclass whose boundingRect() function returns a rectangle that is a static class member.
A very odd situation.


If I want update the static rectangle, do I have to call prepareGeometryChange() on every instance of the class, update the static rectangle, and then call update() on every instance?
You just need to update the static variable and call prepareGeometryChange() on every instance of the class.


What I don't understand is how the scene knows the bounding rectangle has changed, since there is no setter for the bounding rect, only a getter.
It calls boundingRect(). That's why prepareGeometryChange() is required -- it essentially tells graphics view to remove any cached values regarding the size of the object and requery them from the object again.


Does this mean that after you call prepareGeometryChange() the scene begins polling for changes, by calling QGraphicsItem::boundingRect() and comparing that one with what it has stored?
Basically yes.


Does this mean that QGraphicsScene only polls for a change right before control goes back to the event loop (and of course, only if prepareGeometryChange() has been called)?
The scene updates its structures when it decides they need updating. A rule of thumb is that it will happen when some event regarding the scene is being processed.