QDoubleValidator 继承自 QValidator,用于限制 浮点数的输入,比如:

lineEdit->setValidator(new QDoubleValidator);

可限制 QLineEdit 的输入只能是浮点数。同时,还可设置一个输入范围:

QDoubleValidator(double bottom, double top, int decimals, QObject *parent = nullptr)

但在实际使用中发现这个范围没有生效,可能是 Qt 的 bug 吧。那么可以自己实现一个类,继承自 QDoubleValidator 来解决这个问题。实现如下。

  • mydoublevalidator.h
#ifndef MYDOUBLEVALIDATOR_H
#define MYDOUBLEVALIDATOR_H

#include <QDoubleValidator>

class MyDoubleValidator : public QDoubleValidator
{
    Q_OBJECT
public:
    MyDoubleValidator(QObject *parent = nullptr);
    MyDoubleValidator(double bottom, double top, int decimals, QObject *parent = nullptr);
    ~MyDoubleValidator();
    virtual QValidator::State validate(QString &input, int &pos) const;
};

#endif // MYDOUBLEVALIDATOR_H
  • mydoublevalidator.cpp
#include "rms_mydoublevalidator.h"

MyDoubleValidator::MyDoubleValidator(QObject *parent)
    : QDoubleValidator(parent)
{
}

MyDoubleValidator::MyDoubleValidator(double bottom, double top, int decimals, QObject *parent)
    : QDoubleValidator(bottom, top, decimals, parent)
{

}

MyDoubleValidator::~MyDoubleValidator()
{
}

QValidator:: State MyDoubleValidator::validate(QString & input, int & pos) const
{
    if (input.isEmpty())
    {
        return QValidator::Intermediate;
    }
    
    if (bottom() < 0 && input == "-") {
        return QValidator::Acceptable;
    }
    bool OK = false;
    double val = input.toDouble(&OK);

    if (!OK)
    {
        return QValidator::Invalid;
    }

    int dotPos = input.indexOf(".");
    if (dotPos > 0)
    {
        if (input.right(input.length() - dotPos - 1).length() > decimals())
        {
            return QValidator::Invalid;
        }
    }
    if(val<bottom()|| val>top())
        return QValidator::Invalid;
    return QValidator::Acceptable;
}

QIntValidator 也有同样的问题,解决方式和上面类似:

  • myintvalidator.h
#ifndef MYINTVALIDATOR_H
#define MYINTVALIDATOR_H

#include <QIntValidator>

class MyIntValidator : public QIntValidator
{
    Q_OBJECT
public:
    explicit MyIntValidator(QObject *parent = nullptr);
    MyIntValidator(int bottom, int top, QObject *parent = nullptr);

    virtual QValidator::State validate(QString &input, int &pos) const;
};

#endif // MYINTVALIDATOR_H
  • myintvalidator.cpp
#include "rms_myintvalidator.h"

MyIntValidator::MyIntValidator(QObject *parent) : QIntValidator(parent)
{

}

MyIntValidator::MyIntValidator(int bottom, int top, QObject *parent) : QIntValidator(bottom, top, parent)
{

}

QValidator::State MyIntValidator::validate(QString &input, int &pos) const
{
    if (input.isEmpty())
    {
        return QValidator::Intermediate;
    }
    if (bottom() < 0 && input == "-") {
        return QValidator::Acceptable;
    }
    bool OK = false;
    double val = input.toInt(&OK);

    if (!OK)
    {
        return QValidator::Invalid;
    }

    if(val<bottom()|| val>top())
        return QValidator::Invalid;
    return QValidator::Acceptable;
}