1

I am reading this function in QT Docu

It says

QValidator::State QAbstractSpinBox::validate(QString &input, int &pos) const [virtual]

This virtual function is called by the QAbstractSpinBox to determine whether input is valid. The pos parameter indicates the position in the string. Reimplemented in the various subclasses.

I have a weird question because I dont really understand the document. The input here is a string, we determine whether the input is valid or not. So, why do we need the position in the string, for what? I thought the pos here is the length of the string but when I debugged, it is not true. So what does the pos here mean?

UPDATE:

Thanks to @mohabouje. In my case I use a class inherited from QAbstractSpinBox, I override this method and want to validate the string after changed it. How could I update this pos for validating?

QValidator::State MySpinBox::validate( QString &input, int &pos ) const
{
    QString pureValue = stripped( input, &tmpPos, prefix(), suffix() );  //this is my function, i just want to remove also prefix and suffix 
    //I want to add group separator into the pureValue and validate it after that
    //I want to add group separator here, not in the constructor with setGroupSeparatorShown(true);
    //When i add group separator here, the separator appears simultaneously when we type
    //When i set setGroupSeparatorShown(true) in the constructor, it appears after we finish editing and move to another thing (this element loses focus) 
    pureValue.insert(3, locale().groupSeparator());
    input = pureValue;
    
     // I think now 'pos' has changed, how could I update 'pos' to call the following function?
     QValidator::State state = QDoubleSpinBox::validate( input, pos );
     return state;
}
Community
  • 1
  • 1
trangan
  • 341
  • 8
  • 22

1 Answers1

1

I was curious about the underlying implementation. I checked the source code in github.

QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos,
                                                     QValidator::State &state) const
{
    if (cachedText == input && !input.isEmpty()) {
        state = cachedState;
        QSBDEBUG() << "cachedText was '" << cachedText << "' state was "
                   << state << " and value was " << cachedValue;
        return cachedValue;
    }
    const double max = maximum.toDouble();
    const double min = minimum.toDouble();

    QString copy = stripped(input, &pos);
    QSBDEBUG() << "input" << input << "copy" << copy;
    int len = copy.size();
    ...
}

The parameters are used in a private function called stripped. This is the source code:

QString QAbstractSpinBoxPrivate::stripped(const QString &t, int *pos) const
{
    QString text = t;
    if (specialValueText.size() == 0 || text != specialValueText) {
        int from = 0;
        int size = text.size();
        bool changed = false;
        if (prefix.size() && text.startsWith(prefix)) {
            from += prefix.size();
            size -= from;
            changed = true;
        }
        if (suffix.size() && text.endsWith(suffix)) {
            size -= suffix.size();
            changed = true;
        }
        if (changed)
            text = text.mid(from, size);
    }

    const int s = text.size();
    text = text.trimmed();
    if (pos)
        (*pos) -= (s - text.size());
    return text;

}

So, If I understand properly, given a string and prefix/suffix configuration, the function takes the string and computes the real size of the data to be validated, ignoring the prefix and suffix.

The function returns the data already validated that may be parsed to compute the numerical value.

The original value of pos, the function subtract the difference of the size of the text to be validated and the size of the text after performing the trimming operation.

mohabouje
  • 3,867
  • 2
  • 14
  • 28
  • 1
    Be very careful, the repo that you are referring to point to Qt 4.8, and was not updated for 6 years. Most likely the OP is using Qt 5.x, so this can easily lead to incorrect conclusions, even though Widgets don't change that fast. Woboq has it up to date here: https://code.woboq.org/qt5/qtbase/src/widgets/widgets/qspinbox.cpp.html – Adrien Leravat Mar 21 '19 at 00:56
  • thank you very much, could you also help me with my update? – trangan Mar 21 '19 at 10:51
  • I am not pretty sure what are you trying to do, but you can override the default prefix and suffix with the ones you are using ("§" and "km"). It does not make sense to strim the original string to insert a different suffix and prefix, to strim again. If you do that, you don't need to override the validate method. – mohabouje Mar 21 '19 at 11:01
  • @mohabouje: you are right, when I call validate again, then I have to strimm again. But what i want to do is, i want to add `group separator`(point or comma) into the string, and then validate it. So i have to call this `validate` again for the updated string. I do not know how to update `pos` now. (pls see my update) – trangan Mar 21 '19 at 12:04