Details
-
Bug
-
Resolution: Duplicate
-
P2: Important
-
None
-
5.9.0, 5.12.0
-
None
Description
A QValidator subclass was constructed that has a custom Validate method. The idea is to accept only values consisting of P followed by a number, like e.g. P100 or P5. However, the P and the number characters can be entered in random order. If first P is entered the state becomes intermediate and when the number is added the state becomes acceptable. Thus, if the value P5 is entered the validate method will leave it as it is and return acceptable. If first a number is entered the state becomes also intermediate and when the P is entered it is placed in front and the result is also acceptable. So, if a value like 5P is entered the validate method will change it into P5 and also return accceptable.
The problem is that in the last situation described the value of acceptableInput of the QML TextInput will not be updated because there is no acceptableInputChanged signal emitted. It looks like there is a bug in the finishChange method, which will call internalSetText when the text is changed by validate and then return without emitting the signal. The function internalSetText will once more call finishChange, but since in that case acceptableInput is already changed there will also be no signal emitted in the second call. See the code at
https://code.qt.io/cgit/qt/qtdeclarative.git/tree/src/quick/items/qquicktextinput.cpp#n3581
Below the corresponding code of the subclass of the QIntValidator I used. For the sake of simplicity I left out the code that updates a_pos.
Validator.h
#ifndef VALIDATOR_H
#define VALIDATOR_H
#include <QObject>
#include <QPointer>
#include "QIntValidator"
class Validator : public QIntValidator
{ Q_OBJECT public: Validator(QObject * parent = nullptr); QValidator::State validate( QString& a_text, int& a_pos ) const Q_DECL_OVERRIDE; };
#endif // VALIDATOR_H
Validator.cpp
#include "Validator.h"
Validator::Validator(QObject *parent)
: QIntValidator(0, 999, parent)
{
}
Validator::State Validator::validate( QString& a_text, int& a_pos ) const
{
Q_UNUSED(a_pos);
if (a_text.isEmpty())
{ return Validator::Acceptable; }bool containsP = a_text.contains("P");
QString input = a_text.replace("P", "");
a_text = input;
int dummyPos = 0;
State numberState = QIntValidator::validate(input, dummyPos);
if (containsP)
{ a_text.prepend("P"); return numberState; }if (numberState == Acceptable)
{ return Intermediate; }return Invalid;
}
Attachments
Issue Links
- duplicates
-
QTBUG-54582 QQuickTextInput::acceptableInputChanged() sometimes not emitted if string is modified by validator
- Reported