diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 33aa88fffbb..32b43ed4fd5 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -904,8 +904,11 @@ QStyleOptionComboBox QComboBoxPrivateContainer::comboStyleOption() const \fn void QComboBox::currentTextChanged(const QString &text) \since 5.0 - This signal is sent whenever currentText changes. The new value - is passed as \a text. + This signal is emitted whenever currentText changes. + The new value is passed as \a text. + + \note It is not emitted, if currentText remains the same, + even if currentIndex changes. */ /*! @@ -1071,7 +1074,7 @@ void QComboBoxPrivate::_q_dataChanged(const QModelIndex &topLeft, const QModelIn lineEdit->setText(text); updateLineEditGeometry(); } else { - emit q->currentTextChanged(text); + updateCurrentText(text); } q->update(); #if QT_CONFIG(accessibility) @@ -1382,7 +1385,7 @@ void QComboBoxPrivate::_q_emitCurrentIndexChanged(const QModelIndex &index) emit q->currentIndexChanged(index.row()); // signal lineEdit.textChanged already connected to signal currentTextChanged, so don't emit double here if (!lineEdit) - emit q->currentTextChanged(text); + updateCurrentText(text); #if QT_CONFIG(accessibility) QAccessibleValueChangeEvent event(q, text); QAccessible::updateAccessibility(&event); @@ -2848,6 +2851,15 @@ void QComboBoxPrivate::doHidePopup() _q_resetButton(); } +void QComboBoxPrivate::updateCurrentText(const QString &text) +{ + if (text == currentText) + return; + + currentText = text; + emit q_func()->currentTextChanged(text); +} + /*! Clears the combobox, removing all items. diff --git a/src/widgets/widgets/qcombobox_p.h b/src/widgets/widgets/qcombobox_p.h index 18fcc071461..6853e90e67f 100644 --- a/src/widgets/widgets/qcombobox_p.h +++ b/src/widgets/widgets/qcombobox_p.h @@ -357,6 +357,7 @@ public: void updateFocusPolicy(); void showPopupFromMouseEvent(QMouseEvent *e); void doHidePopup(); + void updateCurrentText(const QString &text); #ifdef Q_OS_MAC void cleanupNativePopup(); @@ -382,6 +383,7 @@ public: QPersistentModelIndex currentIndex; QPersistentModelIndex root; QString placeholderText; + QString currentText; QRect hoverRect; QSize iconSize; mutable QSize minimumSizeHint; diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp index 544100b888a..127bef0dd2f 100644 --- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp @@ -1503,42 +1503,70 @@ void tst_QComboBox::currentTextChanged() testWidget->addItems(QStringList() << "foo" << "bar"); QCOMPARE(testWidget->count(), 2); - QSignalSpy spy(testWidget, SIGNAL(currentTextChanged(QString))); + QSignalSpy textChangedSpy(testWidget, &QComboBox::currentTextChanged); testWidget->setEditable(editable); // set text in list testWidget->setCurrentIndex(0); QCOMPARE(testWidget->currentIndex(), 0); - spy.clear(); + textChangedSpy.clear(); testWidget->setCurrentText(QString("bar")); - QCOMPARE(spy.size(), 1); - QCOMPARE(qvariant_cast(spy.at(0).at(0)), QString("bar")); + QCOMPARE(textChangedSpy.size(), 1); + QCOMPARE(qvariant_cast(textChangedSpy.at(0).at(0)), QString("bar")); // set text not in list testWidget->setCurrentIndex(0); QCOMPARE(testWidget->currentIndex(), 0); - spy.clear(); + textChangedSpy.clear(); testWidget->setCurrentText(QString("qt")); if (editable) { - QCOMPARE(spy.size(), 1); - QCOMPARE(qvariant_cast(spy.at(0).at(0)), QString("qt")); + QCOMPARE(textChangedSpy.size(), 1); + QCOMPARE(qvariant_cast(textChangedSpy.at(0).at(0)), QString("qt")); } else { - QCOMPARE(spy.size(), 0); + QCOMPARE(textChangedSpy.size(), 0); } // item changed testWidget->setCurrentIndex(0); QCOMPARE(testWidget->currentIndex(), 0); - spy.clear(); + textChangedSpy.clear(); testWidget->setItemText(0, QString("ape")); - QCOMPARE(spy.size(), 1); - QCOMPARE(qvariant_cast(spy.at(0).at(0)), QString("ape")); + QCOMPARE(textChangedSpy.size(), 1); + QCOMPARE(qvariant_cast(textChangedSpy.at(0).at(0)), QString("ape")); + // change it back - spy.clear(); + textChangedSpy.clear(); testWidget->setItemText(0, QString("foo")); - QCOMPARE(spy.size(), 1); - QCOMPARE(qvariant_cast(spy.at(0).at(0)), QString("foo")); + QCOMPARE(textChangedSpy.size(), 1); + QCOMPARE(qvariant_cast(textChangedSpy.at(0).at(0)), QString("foo")); + + // currentIndexChanged vs. currentTextChanged + testWidget->clear(); + testWidget->addItems(QStringList() << "first" << "second" << "third" << "fourth" << "fourth"); + testWidget->setCurrentIndex(4); + textChangedSpy.clear(); + QSignalSpy indexChangedSpy(testWidget, &QComboBox::currentIndexChanged); + + // Index change w/o text change + testWidget->removeItem(3); + QCOMPARE(textChangedSpy.count(), 0); + QCOMPARE(indexChangedSpy.count(), 1); + + // Index and text change + testWidget->setCurrentIndex(0); + QCOMPARE(textChangedSpy.count(), 1); + QCOMPARE(indexChangedSpy.count(), 2); + + // remove item above current index + testWidget->removeItem(2); + QCOMPARE(textChangedSpy.count(), 1); + QCOMPARE(indexChangedSpy.count(), 2); + + // Text change w/o index change + testWidget->setItemText(0, "first class"); + QCOMPARE(textChangedSpy.count(), 2); + QCOMPARE(indexChangedSpy.count(), 2); } void tst_QComboBox::editTextChanged()