在日常开发过程中QLineEdit作为输入框,有时要限制输入的内容,比哪,考试分数为1-100,这个时候就使用QIntValidator作为限制范围,而如何输入的是带小数的呢,那么使用QDoubleValidator可以吗,下面请看具体的示例。
1.限制输入的最初使用的是正则表达式
1 QRegExp regIntExp("^(([1-9][0-9]|[1-9])|100)$"); 2 QValidator *regIntValidator = new QRegExpValidator(regIntExp, ui->lineEdit); 3 ui->lineEdit->setValidator(regIntValidator);
这个确实比较精确,但这有一个问题,就是范围变化,每次都要重写正则表达式,用起来比较不友好。那么有没有一个比较好的一次设置都通用呢,下面介绍QIntValidator就能达到这种效果,
例如:
1 //1-100整数 2 QIntValidator *intValidator = new QIntValidator(1, 100, this); 3 intValidator->setRange(1, 100); 4 ui->lineEdit->setValidator(intValidator);
这也有两个问题,一是输入多个0都接受了,二是最大范围是3位数可以输到999,如果设置1-99那最大值就是99这没问题,但如果设置为100.输入范围就到999了,那么如果才能消除这两个顶端限制的问题了,这个时候就只能自定义定QIntValidator了。
QIntValidator有两个函数
1 virtual void fixup(QString &input) const override 2 virtual QValidator::State validate(QString &input, int &pos) const override
重写这两个函数,
//validate()是验证的过程,返回结果是State。每当输入有变化时调用此方法
enum State {
Invalid, //验证通不过
Intermediate, //输入未完成,不确定是否能通过验证
Acceptable //验证通过
}
fixup是修复函数,当小于最小值时修复为最小值,例如输入0,自动修复为1
1 #ifndef CUSTOMINTVALIDATOR_H 2 #define CUSTOMINTVALIDATOR_H 3 4 #include <QIntValidator> 5 6 class CustomIntValidator : public QIntValidator 7 { 8 Q_OBJECT 9 public: 10 explicit CustomIntValidator(QObject *parent = nullptr); 11 12 CustomIntValidator(int bottom, int top, QObject *parent); 13 void setRange(int bottom, int top) override; 14 virtual State validate(QString &s, int &n) const override; 15 virtual void fixup(QString &input) const override; 16 17 }; 18 19 #endif // CUSTOMINTVALIDATOR_H
1 #include "customintvalidator.h" 2 #include <QDebug> 3 4 CustomIntValidator::CustomIntValidator(QObject *parent) 5 : QIntValidator{parent} 6 { 7 8 } 9 10 CustomIntValidator::CustomIntValidator(int bottom, int top, QObject *parent) 11 :QIntValidator(bottom, top, parent) 12 { 13 14 } 15 16 void CustomIntValidator::setRange(int bottom, int top) 17 { 18 QIntValidator::setRange(bottom, top); 19 } 20 //validate()是验证的过程,返回结果是State。每当输入有变化时调用此方法 21 //enum State { 22 // Invalid, //验证通不过 23 // Intermediate, //输入未完成,不确定是否能通过验证 24 // Acceptable //验证通过 25 //} 26 QValidator::State CustomIntValidator::validate(QString &s, int &n) const 27 { 28 if (s.isEmpty()) 29 { 30 return QValidator::Intermediate; 31 } 32 //这里判断超过位数了,变成无效的参数 33 int intValue = s.toInt(); 34 if(intValue > top() || intValue < bottom()) 35 return QIntValidator::Invalid; 36 37 return QIntValidator::validate(s, n); 38 } 39 //当验证通不过时,通过调用 QValidator::fixedup()是这个函数修复错误。 40 void CustomIntValidator::fixup(QString &input) const 41 { 42 qDebug() << "fixup============input==============" << input; 43 //这里要做个判断,如果超过最大值取最大值 ,低于最小值取最小值,例如1转换为20, 333转换为100 44 int intValue = input.toInt(); 45 if(intValue < bottom()) 46 input = QString("%1").arg(bottom()); 47 } 48
运行结果:
这种自定义的数据范围调整都不会影响效果,比如你调成20~300,那么他的范围就是在20到300之内,比正则表达式友好些。
下面看浮点数的使用
1.用正则表达式来实现
1 QRegExp regExp("^(([1-9][0-9]|[1-9])(\\.\\d{1,2})?|0\\.\\d{1,2}|100)$"); 2 QValidator *validator = new QRegExpValidator(regExp, ui->lineEdit_3); 3 ui->lineEdit_3->setValidator(validator);
这个比较精准,就是每次范围变化,正则表达式都要重新按规则写。
下面使用QDoubleValidator来限制输入范围。
1 // 0.02-100.0 大于0的浮点数 2 QDoubleValidator *doubleValidator = new QDoubleValidator(this); 3 doubleValidator->setRange(0.02, 100.0, 2); 4 ui->lineEdit_5->setValidator(doubleValidator);
运行结果:
这种怎么是无限制输入呢。
但是仔细一想是Qt的Bug吗,网上查了下也有人遇到说是一个Bug,后来查看帮助说明
一个是标准计数法,一个是科学计数法,默认是科学计数法,所以可以输入任何内容,
如果换成科学计数法呢
1 // 0.02-100.0 大于0的浮点数 2 QDoubleValidator *doubleValidator = new QDoubleValidator(this); 3 doubleValidator->setRange(0.02, 100.0, 2); 4 doubleValidator->setNotation(QDoubleValidator::StandardNotation); 5 ui->lineEdit_5->setValidator(doubleValidator);
运行效果:
但这有一个问题,就是最大值为100的时候输入999也可以,看来最大范围就是输入的位数
那么要消除字个顶端值越界的问题,只能使用自定义的方式,与QIntValidator一样,重写QDoubleValidator的两个函数validate和fixup,下面看代码实现:
1 #ifndef CUSTOMDOUBLEVALIDATOR_H 2 #define CUSTOMDOUBLEVALIDATOR_H 3 4 #include <QDoubleValidator> 5 6 class CustomDoubleValidator : public QDoubleValidator 7 { 8 Q_OBJECT 9 public: 10 explicit CustomDoubleValidator(QObject *parent = nullptr); 11 12 CustomDoubleValidator(double bottom, double top, int decimals = 0, QObject *parent = nullptr); 13 void setRange(double bottom, double top, int decimals = 0) override; 14 virtual State validate(QString &s, int &n) const override; 15 virtual void fixup(QString &input) const override; 16 17 }; 18 19 #endif // CUSTOMDOUBLEVALIDATOR_H
1 #include "customdoublevalidator.h" 2 #include <QDebug> 3 4 CustomDoubleValidator::CustomDoubleValidator(QObject *parent) 5 : QDoubleValidator{parent} 6 { 7 8 } 9 10 CustomDoubleValidator::CustomDoubleValidator(double bottom, double top, int decimals, QObject *parent) 11 :QDoubleValidator(bottom, top, decimals, parent) 12 { 13 14 } 15 16 void CustomDoubleValidator::setRange(double bottom, double top, int decimals) 17 { 18 QDoubleValidator::setRange(bottom, top, decimals); 19 } 20 //validate()是验证的过程,返回结果是State。每当输入有变化时调用此方法 21 //enum State { 22 // Invalid, //验证通不过 23 // Intermediate, //输入未完成,不确定是否能通过验证 24 // Acceptable //验证通过 25 //} 26 QValidator::State CustomDoubleValidator::validate(QString &s, int &n) const 27 { 28 //这里判断超过位数了,"0" , "0." , "0.0"都表示输入未完成 29 if (s.isEmpty() || s == "0" || s == "0." || s == "0.0") 30 { 31 return QValidator::Intermediate; 32 } 33 34 int dotPos = s.indexOf("."); 35 if (dotPos > 0) 36 { 37 int offset = s.length() - dotPos - 1; 38 if (s.right(offset).length() > decimals()) 39 { 40 return QValidator::Invalid; 41 } 42 } 43 44 double value = s.toDouble(); 45 if(value > top() || value < bottom()) { 46 return QValidator::Invalid; 47 } 48 49 return QValidator::Acceptable; 50 } 51 //当验证通不过时,通过调用 QValidator::fixedup()是这个函数修复错误。 52 void CustomDoubleValidator::fixup(QString &input) const 53 { 54 qDebug() << "fixup============input==============" << input; 55 //这里要做个判断,低于最小值取最小值,例如0.01转换为0.02, 56 double value = input.toDouble(); 57 if(value < bottom()) 58 input = QString("%1").arg(bottom()); 59 } 60
完整代码如下:
1 #ifndef MAINWINDOW_H 2 #define MAINWINDOW_H 3 4 #include <QMainWindow> 5 6 7 8 QT_BEGIN_NAMESPACE 9 namespace Ui { class MainWindow; } 10 QT_END_NAMESPACE 11 12 class MainWindow : public QMainWindow 13 { 14 Q_OBJECT 15 16 public: 17 MainWindow(QWidget *parent = nullptr); 18 ~MainWindow(); 19 void initView(); 20 21 private: 22 Ui::MainWindow *ui; 23 }; 24 #endif // MAINWINDOW_H
1 #include "mainwindow.h" 2 #include "ui_mainwindow.h" 3 #include <QRegExpValidator> 4 #include <QIntValidator> 5 #include <QDoubleValidator> 6 #include <QDebug> 7 #include "customintvalidator.h" 8 #include "customdoublevalidator.h" 9 10 MainWindow::MainWindow(QWidget *parent) 11 : QMainWindow(parent) 12 , ui(new Ui::MainWindow) 13 { 14 ui->setupUi(this); 15 initView(); 16 } 17 18 MainWindow::~MainWindow() 19 { 20 delete ui; 21 } 22 23 void MainWindow::initView() 24 { 25 QRegExp regIntExp("^(([1-9][0-9]|[1-9])|100)$"); 26 QValidator *regIntValidator = new QRegExpValidator(regIntExp, ui->lineEdit); 27 ui->lineEdit->setValidator(regIntValidator); 28 //1-100整数 29 QIntValidator *intValidator = new QIntValidator(1, 100, this); 30 intValidator->setRange(1, 100); 31 ui->lineEdit_2->setValidator(intValidator); 32 33 //1-100整数 34 CustomIntValidator *customIntValidator = new CustomIntValidator(1, 100, this); 35 customIntValidator->setRange(1, 100); 36 ui->lineEdit_3->setValidator(customIntValidator); 37 38 // 0.01-100.0 大于0的浮点数 39 QRegExp regExp("^(([1-9][0-9]|[1-9])(\\.\\d{1,2})?|0\\.\\d{1,2}|100)$"); 40 QValidator *validator = new QRegExpValidator(regExp, ui->lineEdit_4); 41 ui->lineEdit_4->setValidator(validator); 42 43 // 0.02-100.0 大于0的浮点数 44 QDoubleValidator *doubleValidator = new QDoubleValidator(this); 45 doubleValidator->setRange(0.02, 100.0, 2); 46 doubleValidator->setNotation(QDoubleValidator::StandardNotation); 47 ui->lineEdit_5->setValidator(doubleValidator); 48 49 CustomDoubleValidator *customDoubleValidator = new CustomDoubleValidator(this); 50 customDoubleValidator->setRange(0.02, 100.0, 2); 51 customDoubleValidator->setNotation(QDoubleValidator::StandardNotation); 52 ui->lineEdit_6->setValidator(customDoubleValidator); 53 54 } 55
运行结果:
标签:QIntValidator,Qt,int,QDoubleValidator,ui,QLineEdit,100,include From: https://www.cnblogs.com/ybqjymy/p/18234866