From a9a48466a10576bdab90c6f26f9c4ae7a87593d8 Mon Sep 17 00:00:00 2001 From: Ivan Solovev Date: Wed, 15 Jun 2022 13:10:10 +0200 Subject: [PATCH] QComboBox: emit currentIndexChanged() and currentTextChanged() when the model is cleared QComboBox uses QPersistentModelIndex to store the current index of the underlying model. When the model is cleared, that index is automatically invalidated, so calling QComboBoxPrivate::setCurrentIndex(QModelIndex()) does not result in signals being emitted, because we do not detect the index change. This patch uses indexBeforeChange to detect such situation and emit all necessary signals. Fixes: QTBUG-103007 Change-Id: I29326830a30a17900839e8d1737a08bd940081ea Reviewed-by: Volker Hilsheimer (cherry picked from commit 662184ac68803aac553921520a1b4b7b23a0633c) Reviewed-by: Qt Cherry-pick Bot --- src/widgets/widgets/qcombobox.cpp | 6 +++- .../widgets/qcombobox/tst_qcombobox.cpp | 33 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 2da6183a1e0..9caac239f96 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -2135,7 +2135,11 @@ void QComboBoxPrivate::setCurrentIndex(const QModelIndex &mi) } updateLineEditGeometry(); } - if (indexChanged) { + // If the model was reset to an empty, currentIndex will be invalidated + // (because it's a QPersistentModelIndex), but the index change will never + // be advertised. So we need an explicit check for such condition. + const bool modelResetToEmpty = !normalized.isValid() && indexBeforeChange != -1; + if (indexChanged || modelResetToEmpty) { q->update(); _q_emitCurrentIndexChanged(currentIndex); } diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp index 987db3e3998..4ca3a1b5a5f 100644 --- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp @@ -146,6 +146,7 @@ private slots: void checkEmbeddedLineEditWhenStyleSheetIsSet(); void propagateStyleChanges(); void buttonPressKeys(); + void clearModel(); private: PlatformInputContext m_platformInputContext; @@ -3593,5 +3594,37 @@ void tst_QComboBox::buttonPressKeys() } } +void tst_QComboBox::clearModel() +{ + using namespace Qt::StringLiterals; + QStringListModel model({ "one"_L1, "two"_L1, "three"_L1 }); + + QComboBox combo; + combo.setModel(&model); + combo.setCurrentIndex(1); + + QCOMPARE(combo.currentIndex(), 1); + QCOMPARE(combo.currentText(), model.index(1).data().toString()); + + QSignalSpy indexSpy(&combo, &QComboBox::currentIndexChanged); + QSignalSpy textSpy(&combo, &QComboBox::currentTextChanged); + + QVERIFY(indexSpy.isEmpty()); + QVERIFY(textSpy.isEmpty()); + + model.setStringList({}); + + QCOMPARE(indexSpy.count(), 1); + const int index = indexSpy.takeFirst().at(0).toInt(); + QCOMPARE(index, -1); + + QCOMPARE(textSpy.count(), 1); + const QString text = textSpy.takeFirst().at(0).toString(); + QCOMPARE(text, QString()); + + QCOMPARE(combo.currentIndex(), -1); + QCOMPARE(combo.currentText(), QString()); +} + QTEST_MAIN(tst_QComboBox) #include "tst_qcombobox.moc"