summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp19
-rw-r--r--tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp19
2 files changed, 38 insertions, 0 deletions
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 25c8030..96710a4 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -740,6 +740,15 @@ void QGraphicsScenePrivate::_q_removeItemLater(QGraphicsItem *item)
unpolishedItems.removeAll(item);
dirtyItems.removeAll(item);
+ //We remove all references of item from the sceneEventFilter arrays
+ QMultiMap<QGraphicsItem*, QGraphicsItem*>::iterator iterator = sceneEventFilters.begin();
+ while (iterator != sceneEventFilters.end()) {
+ if (iterator.value() == item || iterator.key() == item)
+ iterator = sceneEventFilters.erase(iterator);
+ else
+ ++iterator;
+ }
+
// Remove from scene transform cache
int transformIndex = item->d_func()->sceneTransformIndex;
if (transformIndex != -1) {
@@ -3154,6 +3163,16 @@ void QGraphicsScene::removeItem(QGraphicsItem *item)
d->unpolishedItems.removeAll(item);
d->dirtyItems.removeAll(item);
+ //We remove all references of item from the sceneEventFilter arrays
+ QMultiMap<QGraphicsItem*, QGraphicsItem*>::iterator iterator = d->sceneEventFilters.begin();
+ while (iterator != d->sceneEventFilters.end()) {
+ if (iterator.value() == item || iterator.key() == item)
+ iterator = d->sceneEventFilters.erase(iterator);
+ else
+ ++iterator;
+ }
+
+
//Ensure dirty flag have the correct default value so the next time it will be added it will receive updates
item->d_func()->dirty = 0;
item->d_func()->dirtyChildren = 0;
diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
index bc90bf9..e61b69b 100644
--- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
+++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
@@ -4019,6 +4019,25 @@ void tst_QGraphicsItem::sceneEventFilter()
QCOMPARE(tester->filteredEventReceivers.at(6), static_cast<QGraphicsItem *>(text2));
QVERIFY(text2->hasFocus());
+
+ //Let check if the items are correctly removed from the sceneEventFilters array
+ //to avoid stale pointers.
+ QGraphicsView gv;
+ QGraphicsScene *anotherScene = new QGraphicsScene;
+ QGraphicsTextItem *ti = anotherScene->addText("This is a test #1");
+ ti->moveBy(50, 50);
+ QGraphicsTextItem *ti2 = anotherScene->addText("This is a test #2");
+ QGraphicsTextItem *ti3 = anotherScene->addText("This is a test #3");
+ gv.setScene(anotherScene);
+ gv.show();
+ QTest::qWait(250);
+ ti->installSceneEventFilter(ti2);
+ ti3->installSceneEventFilter(ti);
+ delete ti2;
+ //we souldn't crash
+ QTest::mouseMove(gv.viewport(), gv.mapFromScene(ti->scenePos()));
+ QTest::qWait(250);
+ delete ti;
}
class GeometryChanger : public QGraphicsItem