QLineEdit设置数据的输入范围QIntValidator和QDoubleValidator

在日常开发过程中QLineEdit作为输入框,有时要限制输入的内容,比哪,考试分数为1-100,这个时候就使用QIntValidator作为限制范围,而如何输入的是带小数的呢,那么使用QDoubleValidator可以吗,下面请看具体的示例。

1.限制输入的最初使用的是正则表达式

QRegExp regIntExp("^(([1-9][0-9]|[1-9])|100)$"); 
QValidator *regIntValidator = new QRegExpValidator(regIntExp, ui->lineEdit);
ui->lineEdit->setValidator(regIntValidator);

QLineEdit设置数据的输入范围QIntValidator和QDoubleValidator_第1张图片

 这个确实比较精确,但这有一个问题,就是范围变化,每次都要重写正则表达式,用起来比较不友好。那么有没有一个比较好的一次设置都通用呢,下面介绍QIntValidator就能达到这种效果,

例如:

//1-100整数
QIntValidator *intValidator = new QIntValidator(1, 100, this);
intValidator->setRange(1, 100);
ui->lineEdit->setValidator(intValidator);

QLineEdit设置数据的输入范围QIntValidator和QDoubleValidator_第2张图片QLineEdit设置数据的输入范围QIntValidator和QDoubleValidator_第3张图片

这也有两个问题,一是输入多个0都接受了,二是最大范围是3位数可以输到999,如果设置1-99那最大值就是99这没问题,但如果设置为100.输入范围就到999了,那么如果才能消除这两个顶端限制的问题了,这个时候就只能自定义定QIntValidator了。

QIntValidator有两个函数

 virtual void fixup(QString &input) const override
 virtual QValidator::State validate(QString &input, int &pos) const override

重写这两个函数,

//validate()是验证的过程,返回结果是State。每当输入有变化时调用此方法
enum State {
    Invalid,        //验证通不过
   Intermediate,   //输入未完成,不确定是否能通过验证

    Acceptable      //验证通过
}

fixup是修复函数,当小于最小值时修复为最小值,例如输入0,自动修复为1

#ifndef CUSTOMINTVALIDATOR_H
#define CUSTOMINTVALIDATOR_H

#include 

class CustomIntValidator : public QIntValidator
{
    Q_OBJECT
public:
    explicit CustomIntValidator(QObject *parent = nullptr);

    CustomIntValidator(int bottom, int top, QObject *parent);
    void setRange(int bottom, int top) override;
    virtual State validate(QString &s, int &n) const override;
    virtual void fixup(QString &input) const override;

};

#endif // CUSTOMINTVALIDATOR_H

#include "customintvalidator.h"
#include 

CustomIntValidator::CustomIntValidator(QObject *parent)
    : QIntValidator{parent}
{

}

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

}

void CustomIntValidator::setRange(int bottom, int top)
{
    QIntValidator::setRange(bottom, top);
}
//validate()是验证的过程,返回结果是State。每当输入有变化时调用此方法
//enum State {
//    Invalid,        //验证通不过
//    Intermediate,   //输入未完成,不确定是否能通过验证
//    Acceptable      //验证通过
//}
QValidator::State CustomIntValidator::validate(QString &s, int &n) const
{
    if (s.isEmpty())
    {
        return QValidator::Intermediate;
    }
    //这里判断超过位数了,变成无效的参数
    int intValue = s.toInt();
    if(intValue > top() || intValue < bottom())
        return QIntValidator::Invalid;

    return QIntValidator::validate(s, n);
}
//当验证通不过时,通过调用 QValidator::fixedup()是这个函数修复错误。
void CustomIntValidator::fixup(QString &input) const
{
    qDebug() << "fixup============input==============" << input;
    //这里要做个判断,如果超过最大值取最大值 ,低于最小值取最小值,例如1转换为20, 333转换为100
    int intValue = input.toInt();
    if(intValue < bottom())
        input = QString("%1").arg(bottom());
}

运行结果:

QLineEdit设置数据的输入范围QIntValidator和QDoubleValidator_第4张图片

这种自定义的数据范围调整都不会影响效果,比如你调成20~300,那么他的范围就是在20到300之内,比正则表达式友好些。

下面看浮点数的使用

1.用正则表达式来实现

QRegExp regExp("^(([1-9][0-9]|[1-9])(\\.\\d{1,2})?|0\\.\\d{1,2}|100)$");
QValidator *validator = new QRegExpValidator(regExp, ui->lineEdit_3);
ui->lineEdit_3->setValidator(validator);

这个比较精准,就是每次范围变化,正则表达式都要重新按规则写。

QLineEdit设置数据的输入范围QIntValidator和QDoubleValidator_第5张图片

下面使用QDoubleValidator来限制输入范围。

// 0.02-100.0  大于0的浮点数
QDoubleValidator *doubleValidator = new QDoubleValidator(this);
doubleValidator->setRange(0.02, 100.0, 2);
ui->lineEdit_5->setValidator(doubleValidator);

运行结果:

QLineEdit设置数据的输入范围QIntValidator和QDoubleValidator_第6张图片

这种怎么是无限制输入呢。

但是仔细一想是Qt的Bug吗,网上查了下也有人遇到说是一个Bug,后来查看帮助说明

QLineEdit设置数据的输入范围QIntValidator和QDoubleValidator_第7张图片

 一个是标准计数法,一个是科学计数法,默认是科学计数法,所以可以输入任何内容,

如果换成科学计数法呢

// 0.02-100.0  大于0的浮点数
QDoubleValidator *doubleValidator = new QDoubleValidator(this);
doubleValidator->setRange(0.02, 100.0, 2);
doubleValidator->setNotation(QDoubleValidator::StandardNotation);
ui->lineEdit_5->setValidator(doubleValidator);

运行效果:

QLineEdit设置数据的输入范围QIntValidator和QDoubleValidator_第8张图片

但这有一个问题,就是最大值为100的时候输入999也可以,看来最大范围就是输入的位数

QLineEdit设置数据的输入范围QIntValidator和QDoubleValidator_第9张图片

那么要消除字个顶端值越界的问题,只能使用自定义的方式,与QIntValidator一样,重写QDoubleValidator的两个函数validate和fixup,下面看代码实现:

#ifndef CUSTOMDOUBLEVALIDATOR_H
#define CUSTOMDOUBLEVALIDATOR_H

#include 

class CustomDoubleValidator : public QDoubleValidator
{
    Q_OBJECT
public:
    explicit CustomDoubleValidator(QObject *parent = nullptr);

    CustomDoubleValidator(double bottom, double top,  int decimals = 0, QObject *parent = nullptr);
    void setRange(double bottom, double top, int decimals = 0) override;
    virtual State validate(QString &s, int &n) const override;
    virtual void fixup(QString &input) const override;

};

#endif // CUSTOMDOUBLEVALIDATOR_H

#include "customdoublevalidator.h"
#include 

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

}

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

}

void CustomDoubleValidator::setRange(double bottom, double top, int decimals)
{
    QDoubleValidator::setRange(bottom, top, decimals);
}
//validate()是验证的过程,返回结果是State。每当输入有变化时调用此方法
//enum State {
//    Invalid,        //验证通不过
//    Intermediate,   //输入未完成,不确定是否能通过验证
//    Acceptable      //验证通过
//}
QValidator::State CustomDoubleValidator::validate(QString &s, int &n) const
{
    //这里判断超过位数了,"0" , "0." , "0.0"都表示输入未完成
    if (s.isEmpty() || s == "0" || s == "0." || s == "0.0")
    {
        return QValidator::Intermediate;
    }

    int dotPos = s.indexOf(".");
    if (dotPos > 0)
    {
        int offset = s.length() - dotPos - 1;
        if (s.right(offset).length() > decimals())
        {
            return QValidator::Invalid;
        }
    }

    double value = s.toDouble();
    if(value > top() || value < bottom()) {
        return QValidator::Invalid;
    }

    return QValidator::Acceptable;
}
//当验证通不过时,通过调用 QValidator::fixedup()是这个函数修复错误。
void CustomDoubleValidator::fixup(QString &input) const
{
    qDebug() << "fixup============input==============" << input;
    //这里要做个判断,低于最小值取最小值,例如0.01转换为0.02,
    double value = input.toDouble();
    if(value < bottom())
        input = QString("%1").arg(bottom());
}

 QLineEdit设置数据的输入范围QIntValidator和QDoubleValidator_第10张图片

完整代码如下:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 



QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    void initView();

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 
#include 
#include 
#include 
#include "customintvalidator.h"
#include "customdoublevalidator.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    initView();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::initView()
{
    QRegExp regIntExp("^(([1-9][0-9]|[1-9])|100)$");
    QValidator *regIntValidator = new QRegExpValidator(regIntExp, ui->lineEdit);
    ui->lineEdit->setValidator(regIntValidator);
    //1-100整数
    QIntValidator *intValidator = new QIntValidator(1, 100, this);
    intValidator->setRange(1, 100);
    ui->lineEdit_2->setValidator(intValidator);

    //1-100整数
    CustomIntValidator *customIntValidator = new CustomIntValidator(1, 100, this);
    customIntValidator->setRange(1, 100);
    ui->lineEdit_3->setValidator(customIntValidator);

    // 0.01-100.0  大于0的浮点数
    QRegExp regExp("^(([1-9][0-9]|[1-9])(\\.\\d{1,2})?|0\\.\\d{1,2}|100)$");
    QValidator *validator = new QRegExpValidator(regExp, ui->lineEdit_4);
    ui->lineEdit_4->setValidator(validator);

    // 0.02-100.0  大于0的浮点数
    QDoubleValidator *doubleValidator = new QDoubleValidator(this);
    doubleValidator->setRange(0.02, 100.0, 2);
    doubleValidator->setNotation(QDoubleValidator::StandardNotation);
    ui->lineEdit_5->setValidator(doubleValidator);

    CustomDoubleValidator *customDoubleValidator = new CustomDoubleValidator(this);
    customDoubleValidator->setRange(0.02, 100.0, 2);
    customDoubleValidator->setNotation(QDoubleValidator::StandardNotation);
    ui->lineEdit_6->setValidator(customDoubleValidator);

}

运行结果:

QLineEdit设置数据的输入范围QIntValidator和QDoubleValidator_第11张图片

参考:
https://blog.csdn.net/Joker__123/article/details/125517029
https://blog.csdn.net/u011391361/article/details/132101193
https://blog.csdn.net/whik1194/article/details/93504971

你可能感兴趣的:(QT,QT)