Question

Sorry for the vague title.

Currently, if a value is typed into a Q(Double)SpinBox which is out of its range (e.g. typing "100" when max is 90), the value is rejected and instead the last valid value is placed back into the SpinBox.

I want to change this behavior to allow typing out-of-range values which will be automatically corrected (to either the minimum or maximum), because otherwise it would be stupidly hard for the user to guess the value range. After studying the docs and source code of QT, I decided to subclass QSpinBox (will deal with Double variant later) into "QSpinBoxFS", and reimplement both methods mentioned in the title. Somehow though, this is having no effect at all, the behavior is still the same.

These are my methods:

QValidator::State QSpinBoxFS::validate(QString &input,
                                       int &pos)
{
    QIntValidator *validator = new QIntValidator();
    return validator->validate(input, pos);
}

int QSpinBoxFS::valueFromText(const QString &text)
{
    const int max = maximum();
    const int min = minimum();

    QString copy = text;
    int dummy = 0;

    QValidator::State state = validate(copy, dummy);

    if (state == QValidator::Acceptable)
    {
        bool ok;
        int num = locale().toInt(text, &ok, 10);
        if (!ok) { goto bad_text; }

        if (num < min) { return min; }
        if (num > max) { return max; }

        return num;
    }
    else
    {
        bad_text:
        return (max > 0) ? min : max;
    }
}

Of course, this is not really adequate to the pedantic checking done in QSpinBoxPrivate::validateAndInterpret, but I just want the basic concept working for now. I tried changing validate() to always return Acceptable, but weirdly enough the resulting spinboxes would still behave in the old way.

Either a correction of my own methods or a different approach to this problem are welcome! Thank you for your time.

Was it helpful?

Solution

The signatures of the methods you're trying to reimplement are:

QValidator::State validate(QString & input,int & pos) const # <- const!
int valueFromText(const QString & text) const # <- const!

Both your methods are missing the const, so they are different methods and thus never called from the base class.

OTHER TIPS

On a different note,

QAbstractSpinButton::setCorrectionMode(QAbstractSpinBox::CorrectToNearestValue)

can achieve somehwat similar results (typing values smaller than min will be corrected to min), although you are still prevented from typing values greater than max due to the validator. (And therefor it is insufficient for my needs, just leaving it here for reference.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top