QSpinBox enters NaN as valid value
I am trying to extend QSpinBox to be able to enter "NaN" or "nan" as a valid value. According to the documentation, I have to use textFromValue, valueFromText and check functions to accomplish this, but I can't get it to work as it still won't allow me to enter text other than numbers. This 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 that is missing? or do it wrong? If theres an easier way to do this as well, it would be great to know ...
source to share
Signature QAbstractSpinBox::validate()
:
QValidator::State QAbstractSpinBox::validate ( QString & input, int & pos ) const
So your method signature validate()
differs in two ways: its not const
, but yours int pos
instead int& pos
. Thus, it does not override QAbstractSpinBox::validate
and is never called QAbstractSpinBox
.
source to share
If you can extend the lower end of your range by -1 and use normal QSpinBox
or QDoubleSpinBox
and call spinbox->specialValueText("nan")
that will show the string nan
when value() == minimum()
. The user will not be able to enter the string "nan" manually, but you can always accompany the player with a button that executes spinbox->setValue(spinbox->minimum())
. Here's a compiled 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"
source to share