QLineEdit: don't emit editingFinished if nothing was done

When a modal dialog is called from a slot connected to the
editingFinished signal, the chain of events resulting from the focus
returning to this widget will make the editingFinished signal emitted
again. This patch uses a new variable to keep track of the fact that
there was a modification. Once editingFinished was emitted, that flag
is cleared so next time the signal will be emitted again only if a
modification was made to the line edit content.

[ChangeLog][QtWidget][QLineEdit] Behavior change: now the
editingFinished signal is emitted only once after the line edit content
was edited.

Fixes: QTBUG-40
Change-Id: Ia4760bad8717f1758c3939132c446b4b4c6cd498
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
This commit is contained in:
Samuel Gaist 2018-11-25 21:58:47 +01:00
parent df2b76046d
commit dd1a630871
4 changed files with 28 additions and 5 deletions

View File

@ -315,7 +315,7 @@ QString QLineEdit::text() const
void QLineEdit::setText(const QString& text)
{
Q_D(QLineEdit);
d->control->setText(text);
d->setText(text);
}
/*!
@ -1483,8 +1483,11 @@ bool QLineEdit::event(QEvent * e)
} else if (e->type() == QEvent::LeaveEditFocus) {
d->setCursorVisible(false);
d->control->setCursorBlinkEnabled(false);
if (d->control->hasAcceptableInput() || d->control->fixup())
if (d->edited && (d->control->hasAcceptableInput()
|| d->control->fixup())) {
emit editingFinished();
d->edited = false;
}
}
}
#endif
@ -1891,7 +1894,6 @@ void QLineEdit::focusInEvent(QFocusEvent *e)
/*!\reimp
*/
void QLineEdit::focusOutEvent(QFocusEvent *e)
{
Q_D(QLineEdit);
@ -1914,8 +1916,10 @@ void QLineEdit::focusOutEvent(QFocusEvent *e)
#endif
if (reason != Qt::PopupFocusReason
|| !(QApplication::activePopupWidget() && QApplication::activePopupWidget()->parentWidget() == this)) {
if (hasAcceptableInput() || d->control->fixup())
if (d->edited && (hasAcceptableInput() || d->control->fixup())) {
emit editingFinished();
d->edited = false;
}
}
#ifdef QT_KEYPAD_NAVIGATION
d->control->setCancelText(QString());

View File

@ -127,6 +127,7 @@ void QLineEditPrivate::_q_handleWindowActivate()
void QLineEditPrivate::_q_textEdited(const QString &text)
{
Q_Q(QLineEdit);
edited = true;
emit q->textEdited(text);
#if QT_CONFIG(completer)
if (control->completer()
@ -272,6 +273,12 @@ void QLineEditPrivate::setCursorVisible(bool visible)
q->update();
}
void QLineEditPrivate::setText(const QString& text)
{
edited = true;
control->setText(text);
}
void QLineEditPrivate::updatePasswordEchoEditing(bool editing)
{
Q_Q(QLineEdit);

View File

@ -151,7 +151,7 @@ public:
QLineEditPrivate()
: control(0), frame(1), contextMenuEnabled(1), cursorVisible(0),
dragEnabled(0), clickCausedFocus(0), hscroll(0), vscroll(0),
dragEnabled(0), clickCausedFocus(0), edited(0), hscroll(0), vscroll(0),
alignment(Qt::AlignLeading | Qt::AlignVCenter),
leftTextMargin(0), topTextMargin(0), rightTextMargin(0), bottomTextMargin(0),
lastTextSize(0), mouseYThreshold(0)
@ -176,6 +176,7 @@ public:
bool inSelection(int x) const;
QRect cursorRect() const;
void setCursorVisible(bool visible);
void setText(const QString& text);
void updatePasswordEchoEditing(bool);
@ -202,6 +203,7 @@ public:
uint cursorVisible : 1;
uint dragEnabled : 1;
uint clickCausedFocus : 1;
uint edited : 1;
int hscroll;
int vscroll;
uint alignment;

View File

@ -3613,6 +3613,14 @@ void tst_QLineEdit::task174640_editingFinished()
QTRY_VERIFY(le1->hasFocus());
QCOMPARE(editingFinishedSpy.count(), 0);
le2->setFocus();
QTRY_VERIFY(le2->hasFocus());
// editingFinished will not be emitted anew because no editing happened
QCOMPARE(editingFinishedSpy.count(), 0);
le1->setFocus();
QTRY_VERIFY(le1->hasFocus());
QTest::keyPress(le1, Qt::Key_Plus);
le2->setFocus();
QTRY_VERIFY(le2->hasFocus());
QCOMPARE(editingFinishedSpy.count(), 1);
@ -3632,6 +3640,8 @@ void tst_QLineEdit::task174640_editingFinished()
delete testMenu1;
QCOMPARE(editingFinishedSpy.count(), 0);
QTRY_VERIFY(le1->hasFocus());
// Ensure le1 has been edited
QTest::keyPress(le1, Qt::Key_Plus);
QMenu *testMenu2 = new QMenu(le2);
testMenu2->addAction("foo2");