问题
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...
回答1:
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
.
回答2:
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"
回答3:
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.
来源:https://stackoverflow.com/questions/10133336/qspinbox-enter-nan-as-a-valid-value