Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-75817

TextInput does not update acceptableInput when input is changed in validate

    XMLWordPrintable

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

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

              qt.team.quick.subscriptions Qt Quick and Widgets Team
              patrickz Patrick Zwietering
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes