diff options
-rw-r--r-- | src/widgets/graphicsview/qgraphicsscene.cpp | 11 | ||||
-rw-r--r-- | tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp | 48 |
2 files changed, 56 insertions, 3 deletions
diff --git a/src/widgets/graphicsview/qgraphicsscene.cpp b/src/widgets/graphicsview/qgraphicsscene.cpp index 411eee0c4f..f65082ad55 100644 --- a/src/widgets/graphicsview/qgraphicsscene.cpp +++ b/src/widgets/graphicsview/qgraphicsscene.cpp @@ -2251,11 +2251,16 @@ void QGraphicsScene::clearSelection() ++d->selectionChanging; // iterate over a copy, as clearing selection might invalidate selectedItems const auto selectedItems = d->selectedItems; - bool changed = !selectedItems.isEmpty(); + QSet<QGraphicsItem *> stillSelectedSet; - for (QGraphicsItem *item : selectedItems) + for (QGraphicsItem *item : selectedItems) { item->setSelected(false); - d->selectedItems.clear(); + // items might override itemChange to prevent deselection + if (item->isSelected()) + stillSelectedSet << item; + } + const bool changed = stillSelectedSet != selectedItems; + d->selectedItems = stillSelectedSet; // Re-enable emitting selectionChanged() for individual items. --d->selectionChanging; diff --git a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp index cc92f3b65b..e639da3e7c 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp @@ -253,6 +253,7 @@ private slots: void focusItemChangedSignal(); void minimumRenderSize(); void focusOnTouch(); + void clearSelection(); // task specific tests below me void task139710_bspTreeCrash(); @@ -4834,6 +4835,53 @@ void tst_QGraphicsScene::focusOnTouch() QVERIFY(rect->hasFocus()); } +void tst_QGraphicsScene::clearSelection() +{ + class AlwaysSelectedItem : public QGraphicsRectItem + { + public: + using QGraphicsRectItem::QGraphicsRectItem; + protected: + QVariant itemChange(GraphicsItemChange change, const QVariant& value) + { + if (change == ItemSelectedChange) + return true; + return QGraphicsRectItem::itemChange(change, value); + } + }; + QGraphicsScene scene; + QSignalSpy spy(&scene, &QGraphicsScene::selectionChanged); + + QGraphicsRectItem *regularRect = new QGraphicsRectItem; + regularRect->setFlag(QGraphicsItem::ItemIsSelectable); + regularRect->setRect(0, 0, 50, 50); + regularRect->setSelected(true); + AlwaysSelectedItem *selectedRect = new AlwaysSelectedItem; + selectedRect->setFlag(QGraphicsItem::ItemIsSelectable); + selectedRect->setRect(50, 50, 50, 50); + selectedRect->setSelected(true); + scene.addItem(regularRect); + scene.addItem(selectedRect); + + QCOMPARE(spy.count(), 2); + + QCOMPARE(scene.selectedItems().count(), 2); + scene.clearSelection(); + QVERIFY(!regularRect->isSelected()); + QVERIFY(selectedRect->isSelected()); + QCOMPARE(scene.selectedItems().count(), 1); + QCOMPARE(spy.count(), 3); + + delete regularRect; + QCOMPARE(spy.count(), 3); + + scene.clearSelection(); + QCOMPARE(spy.count(), 3); + + delete selectedRect; + QCOMPARE(spy.count(), 4); +} + void tst_QGraphicsScene::taskQTBUG_15977_renderWithDeviceCoordinateCache() { QGraphicsScene scene; |