Question

I am trying to extend the QSpinBox to be able to enter "NaN" or "nan" as a valid value. According to the documentation i should use the textFromValue, valueFromText, and validate functions to accomplish this but i cant get it to work since its still not allowing me to enter any text besides numbers. Here is what i have in my .h and .cpp files:

CPP file:

#include "CustomIntSpinBox.h"

CustomIntSpinBox::CustomIntSpinBox(QWidget *parent) : QSpinBox(parent)
{
    this->setRange(-32767,32767);
}

QString CustomIntSpinBox::textFromValue(int value) const
{
    if (value == NAN_VALUE)
    {
        return QString::fromStdString("nan");
    }
    else
    {
        return QString::number(value);
    }
}

int CustomIntSpinBox::valueFromText(const QString &text) const
{
    if (text.toLower() == QString::fromStdString("nan"))
    {
        return NAN_VALUE;
    }
    else
    {
        return text.toInt();
    }
}

QValidator::State validate(QString &input, int pos)
{
    return QValidator::Acceptable;
}

H file:

#ifndef CUSTOMINTSPINBOX_H
#define CUSTOMINTSPINBOX_H

#include <QSpinBox>
#include <QWidget>
#include <QtGui>
#include <iostream>

using namespace std;

#define NAN_VALUE 32767

class CustomIntSpinBox : public QSpinBox
{
    Q_OBJECT

public:
    CustomIntSpinBox(QWidget *parent = 0);
    virtual ~CustomIntSpinBox() throw() {}

    int valueFromText(const QString &text) const;
    QString textFromValue(int value) const;
    QValidator::State validate(QString &input, int pos);
};

#endif // CUSTOMINTSPINBOX_H

Is there something im missing? or doing wrong? If theres and easier way to do this also that would be great to know...

Was it helpful?

Solution

The signature of QAbstractSpinBox::validate() is:

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

So your validate() method's signature differs in two ways: its not const, and you have int pos instead of int& pos. Thus it doesn't override QAbstractSpinBox::validate and is never called by QAbstractSpinBox.

OTHER TIPS

If you can extend the lower bound of your range by -1 and use a normal QSpinBox or QDoubleSpinBox and call spinbox->specialValueText("nan"), which will show the string nan when value() == minimum(). The user won't be able to enter the string "nan" manually, but you can always accompany the spinbox with a button that executes spinbox->setValue(spinbox->minimum()). Here's a compilable example:

// main.cpp
#include <QSpinBox>
#include <QDoubleSpinBox>
#include <QDialog>
#include <QApplication>
#include <QVBoxLayout>

#include <limits>

class Tester : public QDialog {
    Q_OBJECT
public:
    static const int NanValue = -32767-1;
    explicit Tester(QWidget * parent=0)
        : QDialog(parent),
          m_spinBox(new QSpinBox(this)),
          m_doubleSpinBox(new QDoubleSpinBox(this))
    {
        QVBoxLayout * vlay = new QVBoxLayout(this);
        vlay->addWidget(m_spinBox);
        vlay->addWidget(m_doubleSpinBox);

        m_spinBox->setRange(NanValue,32767);
        m_doubleSpinBox->setRange(NanValue,32767);

        m_spinBox->setValue(NanValue);
        m_doubleSpinBox->setValue(NanValue);

        updateSpecialValueText();
    }

protected:
    void changeEvent(QEvent *e) {
        QDialog::changeEvent(e);
        if (e->type() == QEvent::LocaleChange)
            updateSpecialValueText();
    }


private:
    void updateSpecialValueText() {
        static const double NaN = std::numeric_limits<double>::quiet_NaN();
        m_spinBox->setSpecialValueText(locale().toString(NaN));
        m_doubleSpinBox->setSpecialValueText(locale().toString(NaN));
    }

private:
    QSpinBox * m_spinBox;
    QDoubleSpinBox * m_doubleSpinBox;
};

int main(int argc, char * argv[]) {
    QApplication app(argc, argv);

    Tester t;
    return t.exec();
}

#include "main.moc"

Maybe QSpinBox sets a lineEdit wich has a QIntValidator as QValidator. At least the docs of QAbstractSpinBox::setLineEdit suggest that the validator of the lineEdit has priority over the QAbstractSpinBox::validate function.

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