I have a set of QLineEdits
that are supposed to accept double values within a certain range, (e.g., -15 to 15).
I have something along these lines when setting up each:
lineEdit->setValidator(new QDoubleValidator(minVal, maxVal, 5, lineEdit));
Ideally, the line edits would work such that only values in range can be entered. When I tried this out, I noticed that only numbers could be typed, as desired, but that they could still go out of range.
How can I dynamically force the input to fit into the range (e.g., if range is -15 to 15 and user types a 1, then attempts to type a 9, it doesn't work/display the 9...but typing 1 and then 2 does work/display the 2.) ?
Do I need to connect and call the validate()
function somewhere?
That's because QDoubleValidator
returns QValidator::Intermediate
if the value is outside the bounds and QLineEdit
accepts QValidator::Intermediate
values.
To implement the behavior you want you can make your own QDoubleValidator
subclass like this:
class MyValidator : public QDoubleValidator
{
public:
MyValidator(double bottom, double top, int decimals, QObject * parent) :
QDoubleValidator(bottom, top, decimals, parent)
{
}
QValidator::State validate(QString &s, int &i) const
{
if (s.isEmpty()) {
return QValidator::Intermediate;
}
bool ok;
double d = s.toDouble(&ok);
if (ok && d > 0 && d < 15) {
return QValidator::Acceptable;
} else {
return QValidator::Invalid;
}
}
};
UPDATE: This will solve the negative sign issue, and also will accept locale double formats:
class MyValidator : public QDoubleValidator
{
public:
MyValidator(double bottom, double top, int decimals, QObject * parent) :
QDoubleValidator(bottom, top, decimals, parent)
{
}
QValidator::State validate(QString &s, int &i) const
{
if (s.isEmpty() || s == "-") {
return QValidator::Intermediate;
}
QChar decimalPoint = locale().decimalPoint();
if(s.indexOf(decimalPoint) != -1) {
int charsAfterPoint = s.length() - s.indexOf(decimalPoint) - 1;
if (charsAfterPoint > decimals()) {
return QValidator::Invalid;
}
}
bool ok;
double d = locale().toDouble(s, &ok);
if (ok && d >= bottom() && d <= top()) {
return QValidator::Acceptable;
} else {
return QValidator::Invalid;
}
}
};