Fix no-op emission of QComboBox::currentTextChanged
currentTextChanged is emitted when the current index changes and the current text doesn't. This can be the case, if - old and new index have identical text values - an item is removed below the current index [ChangeLog][Widgets][QComboBox] emit currentTextChanged only, if currentText changes. Add a corresponding test in tst_QComboBox::currentText(). Fixes: QTBUG-113717 Change-Id: I847874f0792b29a2841e50bb82d06ad496fb02c3 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> (cherry picked from commit 9195438a5fd88c676b0fc4abd429bcffa6f97e24) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
b49593c0c8
commit
56598b65fa
@ -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.
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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<QString>(spy.at(0).at(0)), QString("bar"));
|
||||
QCOMPARE(textChangedSpy.size(), 1);
|
||||
QCOMPARE(qvariant_cast<QString>(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<QString>(spy.at(0).at(0)), QString("qt"));
|
||||
QCOMPARE(textChangedSpy.size(), 1);
|
||||
QCOMPARE(qvariant_cast<QString>(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<QString>(spy.at(0).at(0)), QString("ape"));
|
||||
QCOMPARE(textChangedSpy.size(), 1);
|
||||
QCOMPARE(qvariant_cast<QString>(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<QString>(spy.at(0).at(0)), QString("foo"));
|
||||
QCOMPARE(textChangedSpy.size(), 1);
|
||||
QCOMPARE(qvariant_cast<QString>(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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user