diff options
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene.cpp | 19 | ||||
-rw-r--r-- | tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 19 |
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 |