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)
|
\fn void QComboBox::currentTextChanged(const QString &text)
|
||||||
\since 5.0
|
\since 5.0
|
||||||
|
|
||||||
This signal is sent whenever currentText changes. The new value
|
This signal is emitted whenever currentText changes.
|
||||||
is passed as \a text.
|
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);
|
lineEdit->setText(text);
|
||||||
updateLineEditGeometry();
|
updateLineEditGeometry();
|
||||||
} else {
|
} else {
|
||||||
emit q->currentTextChanged(text);
|
updateCurrentText(text);
|
||||||
}
|
}
|
||||||
q->update();
|
q->update();
|
||||||
#if QT_CONFIG(accessibility)
|
#if QT_CONFIG(accessibility)
|
||||||
@ -1382,7 +1385,7 @@ void QComboBoxPrivate::_q_emitCurrentIndexChanged(const QModelIndex &index)
|
|||||||
emit q->currentIndexChanged(index.row());
|
emit q->currentIndexChanged(index.row());
|
||||||
// signal lineEdit.textChanged already connected to signal currentTextChanged, so don't emit double here
|
// signal lineEdit.textChanged already connected to signal currentTextChanged, so don't emit double here
|
||||||
if (!lineEdit)
|
if (!lineEdit)
|
||||||
emit q->currentTextChanged(text);
|
updateCurrentText(text);
|
||||||
#if QT_CONFIG(accessibility)
|
#if QT_CONFIG(accessibility)
|
||||||
QAccessibleValueChangeEvent event(q, text);
|
QAccessibleValueChangeEvent event(q, text);
|
||||||
QAccessible::updateAccessibility(&event);
|
QAccessible::updateAccessibility(&event);
|
||||||
@ -2848,6 +2851,15 @@ void QComboBoxPrivate::doHidePopup()
|
|||||||
_q_resetButton();
|
_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.
|
Clears the combobox, removing all items.
|
||||||
|
|
||||||
|
@ -357,6 +357,7 @@ public:
|
|||||||
void updateFocusPolicy();
|
void updateFocusPolicy();
|
||||||
void showPopupFromMouseEvent(QMouseEvent *e);
|
void showPopupFromMouseEvent(QMouseEvent *e);
|
||||||
void doHidePopup();
|
void doHidePopup();
|
||||||
|
void updateCurrentText(const QString &text);
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
void cleanupNativePopup();
|
void cleanupNativePopup();
|
||||||
@ -382,6 +383,7 @@ public:
|
|||||||
QPersistentModelIndex currentIndex;
|
QPersistentModelIndex currentIndex;
|
||||||
QPersistentModelIndex root;
|
QPersistentModelIndex root;
|
||||||
QString placeholderText;
|
QString placeholderText;
|
||||||
|
QString currentText;
|
||||||
QRect hoverRect;
|
QRect hoverRect;
|
||||||
QSize iconSize;
|
QSize iconSize;
|
||||||
mutable QSize minimumSizeHint;
|
mutable QSize minimumSizeHint;
|
||||||
|
@ -1503,42 +1503,70 @@ void tst_QComboBox::currentTextChanged()
|
|||||||
testWidget->addItems(QStringList() << "foo" << "bar");
|
testWidget->addItems(QStringList() << "foo" << "bar");
|
||||||
QCOMPARE(testWidget->count(), 2);
|
QCOMPARE(testWidget->count(), 2);
|
||||||
|
|
||||||
QSignalSpy spy(testWidget, SIGNAL(currentTextChanged(QString)));
|
QSignalSpy textChangedSpy(testWidget, &QComboBox::currentTextChanged);
|
||||||
|
|
||||||
testWidget->setEditable(editable);
|
testWidget->setEditable(editable);
|
||||||
|
|
||||||
// set text in list
|
// set text in list
|
||||||
testWidget->setCurrentIndex(0);
|
testWidget->setCurrentIndex(0);
|
||||||
QCOMPARE(testWidget->currentIndex(), 0);
|
QCOMPARE(testWidget->currentIndex(), 0);
|
||||||
spy.clear();
|
textChangedSpy.clear();
|
||||||
testWidget->setCurrentText(QString("bar"));
|
testWidget->setCurrentText(QString("bar"));
|
||||||
QCOMPARE(spy.size(), 1);
|
QCOMPARE(textChangedSpy.size(), 1);
|
||||||
QCOMPARE(qvariant_cast<QString>(spy.at(0).at(0)), QString("bar"));
|
QCOMPARE(qvariant_cast<QString>(textChangedSpy.at(0).at(0)), QString("bar"));
|
||||||
|
|
||||||
// set text not in list
|
// set text not in list
|
||||||
testWidget->setCurrentIndex(0);
|
testWidget->setCurrentIndex(0);
|
||||||
QCOMPARE(testWidget->currentIndex(), 0);
|
QCOMPARE(testWidget->currentIndex(), 0);
|
||||||
spy.clear();
|
textChangedSpy.clear();
|
||||||
testWidget->setCurrentText(QString("qt"));
|
testWidget->setCurrentText(QString("qt"));
|
||||||
if (editable) {
|
if (editable) {
|
||||||
QCOMPARE(spy.size(), 1);
|
QCOMPARE(textChangedSpy.size(), 1);
|
||||||
QCOMPARE(qvariant_cast<QString>(spy.at(0).at(0)), QString("qt"));
|
QCOMPARE(qvariant_cast<QString>(textChangedSpy.at(0).at(0)), QString("qt"));
|
||||||
} else {
|
} else {
|
||||||
QCOMPARE(spy.size(), 0);
|
QCOMPARE(textChangedSpy.size(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// item changed
|
// item changed
|
||||||
testWidget->setCurrentIndex(0);
|
testWidget->setCurrentIndex(0);
|
||||||
QCOMPARE(testWidget->currentIndex(), 0);
|
QCOMPARE(testWidget->currentIndex(), 0);
|
||||||
spy.clear();
|
textChangedSpy.clear();
|
||||||
testWidget->setItemText(0, QString("ape"));
|
testWidget->setItemText(0, QString("ape"));
|
||||||
QCOMPARE(spy.size(), 1);
|
QCOMPARE(textChangedSpy.size(), 1);
|
||||||
QCOMPARE(qvariant_cast<QString>(spy.at(0).at(0)), QString("ape"));
|
QCOMPARE(qvariant_cast<QString>(textChangedSpy.at(0).at(0)), QString("ape"));
|
||||||
|
|
||||||
// change it back
|
// change it back
|
||||||
spy.clear();
|
textChangedSpy.clear();
|
||||||
testWidget->setItemText(0, QString("foo"));
|
testWidget->setItemText(0, QString("foo"));
|
||||||
QCOMPARE(spy.size(), 1);
|
QCOMPARE(textChangedSpy.size(), 1);
|
||||||
QCOMPARE(qvariant_cast<QString>(spy.at(0).at(0)), QString("foo"));
|
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()
|
void tst_QComboBox::editTextChanged()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user