PDA

View Full Version : QT 4.6.3 bug? QGraphicsItem receives paint even when removed from scene?!



jonks
30th August 2010, 02:17
Hi,

I`ve got a situation that I`ve been trying to fix for a few days:

I have a scene that contains a single object derived from QGraphicsItem.
If I remove the object from the scene (calling QGraphicsScene::removeItem()) and then delete the pointer to the object, my program crashes later when the QGraphicsScene repaints.

Basically, it turns out the item I removed from the scene is still in the Qt's internal BSP tree representation of the scene. This happens even though a call to QGraphicsScene::items().count() (after deleting the item) returns 0.

- QGraphicsScene derefences the pointer to the object that has been removed and deleted.

If I don't delete the object (i.e. free the memory allocated to it) then QT still renders the object even though the scene is empty (QGraphicsScene::items().count() returns 0) !!!

Does anyone have any ideas what could cause this? Is QT performing reference counting or something.

Is it necessary to call another function to invalidate QT's BSP tree?

Sorry - there is too much code in the project to paste.

SixDegrees
30th August 2010, 08:46
Can you duplicate the problem in a simple implementation? A QGraphicsView looking at a QGraphicsScene while adding and removing a single QGraphicsItem, for example.

It certainly could be a bug in Qt. But I'd check your own code first, looking for dangling references or multiple addItem() calls that may be part of the problem. Running through a tool like valgrind (under Linux) might be instructive.

Also, what happens if you have more than one item, and remove the second-to-last item from the scene? Same behavior? If it's only related to the last item being removed, you could stuff a small, invisible "dummy" item in the scene as a workaround.

wysota
30th August 2010, 09:22
I'd check whether you are not removing an object from the scene (and deleting it) upon receiving a signal carrying the item somewhere within its arguments.

jonks
30th August 2010, 14:13
The bug only happens when I resize an item and make it smaller than the original size.

I created a small prog to reproduce it and while in the Qt code in the call stack I found a check for changedSignalIndex.
Googled for that, and came across this post (http://www.qtcentre.org/threads/28749-Qt-4.6-GraphicsView-items-remove-problem)

I had neglected to call
QGraphicsItem::prepareGeometryChange() when changing the item's bounding rect.
Failing to call this results in a pointer to my object remaining in the BSP tree.

Thank goodness for opensource code! I don't think I would have discovered the necessity to call prepareGeometryChange by reading the docs.

wysota
30th August 2010, 14:37
I don't think I would have discovered the necessity to call prepareGeometryChange by reading the docs.

Right, there surely is no sentence in the docs such as this one:

If you want to change an item's geometry in any way, you must first call prepareGeometryChange() to allow QGraphicsScene to update its bookkeeping