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


    在日常开发过程中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有两个函数

     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

    1. #ifndef CUSTOMINTVALIDATOR_H
    2. #define CUSTOMINTVALIDATOR_H
    3. #include
    4. class CustomIntValidator : public QIntValidator
    5. {
    6. Q_OBJECT
    7. public:
    8. explicit CustomIntValidator(QObject *parent = nullptr);
    9. CustomIntValidator(int bottom, int top, QObject *parent);
    10. void setRange(int bottom, int top) override;
    11. virtual State validate(QString &s, int &n) const override;
    12. virtual void fixup(QString &input) const override;
    13. };
    14. #endif // CUSTOMINTVALIDATOR_H

    1. #include "customintvalidator.h"
    2. #include
    3. CustomIntValidator::CustomIntValidator(QObject *parent)
    4. : QIntValidator{parent}
    5. {
    6. }
    7. CustomIntValidator::CustomIntValidator(int bottom, int top, QObject *parent)
    8. :QIntValidator(bottom, top, parent)
    9. {
    10. }
    11. void CustomIntValidator::setRange(int bottom, int top)
    12. {
    13. QIntValidator::setRange(bottom, top);
    14. }
    15. //validate()是验证的过程,返回结果是State。每当输入有变化时调用此方法
    16. //enum State {
    17. // Invalid, //验证通不过
    18. // Intermediate, //输入未完成,不确定是否能通过验证
    19. // Acceptable //验证通过
    20. //}
    21. QValidator::State CustomIntValidator::validate(QString &s, int &n) const
    22. {
    23. if (s.isEmpty())
    24. {
    25. return QValidator::Intermediate;
    26. }
    27. //这里判断超过位数了,变成无效的参数
    28. int intValue = s.toInt();
    29. if(intValue > top() || intValue < bottom())
    30. return QIntValidator::Invalid;
    31. return QIntValidator::validate(s, n);
    32. }
    33. //当验证通不过时,通过调用 QValidator::fixedup()是这个函数修复错误。
    34. void CustomIntValidator::fixup(QString &input) const
    35. {
    36. qDebug() << "fixup============input==============" << input;
    37. //这里要做个判断,如果超过最大值取最大值 ,低于最小值取最小值,例如1转换为20, 333转换为100
    38. int intValue = input.toInt();
    39. if(intValue < bottom())
    40. input = QString("%1").arg(bottom());
    41. }

    运行结果:

    这种自定义的数据范围调整都不会影响效果,比如你调成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. #include
    4. class CustomDoubleValidator : public QDoubleValidator
    5. {
    6. Q_OBJECT
    7. public:
    8. explicit CustomDoubleValidator(QObject *parent = nullptr);
    9. CustomDoubleValidator(double bottom, double top, int decimals = 0, QObject *parent = nullptr);
    10. void setRange(double bottom, double top, int decimals = 0) override;
    11. virtual State validate(QString &s, int &n) const override;
    12. virtual void fixup(QString &input) const override;
    13. };
    14. #endif // CUSTOMDOUBLEVALIDATOR_H

    1. #include "customdoublevalidator.h"
    2. #include
    3. CustomDoubleValidator::CustomDoubleValidator(QObject *parent)
    4. : QDoubleValidator{parent}
    5. {
    6. }
    7. CustomDoubleValidator::CustomDoubleValidator(double bottom, double top, int decimals, QObject *parent)
    8. :QDoubleValidator(bottom, top, decimals, parent)
    9. {
    10. }
    11. void CustomDoubleValidator::setRange(double bottom, double top, int decimals)
    12. {
    13. QDoubleValidator::setRange(bottom, top, decimals);
    14. }
    15. //validate()是验证的过程,返回结果是State。每当输入有变化时调用此方法
    16. //enum State {
    17. // Invalid, //验证通不过
    18. // Intermediate, //输入未完成,不确定是否能通过验证
    19. // Acceptable //验证通过
    20. //}
    21. QValidator::State CustomDoubleValidator::validate(QString &s, int &n) const
    22. {
    23. //这里判断超过位数了,"0" , "0." , "0.0"都表示输入未完成
    24. if (s.isEmpty() || s == "0" || s == "0." || s == "0.0")
    25. {
    26. return QValidator::Intermediate;
    27. }
    28. int dotPos = s.indexOf(".");
    29. if (dotPos > 0)
    30. {
    31. int offset = s.length() - dotPos - 1;
    32. if (s.right(offset).length() > decimals())
    33. {
    34. return QValidator::Invalid;
    35. }
    36. }
    37. double value = s.toDouble();
    38. if(value > top() || value < bottom()) {
    39. return QValidator::Invalid;
    40. }
    41. return QValidator::Acceptable;
    42. }
    43. //当验证通不过时,通过调用 QValidator::fixedup()是这个函数修复错误。
    44. void CustomDoubleValidator::fixup(QString &input) const
    45. {
    46. qDebug() << "fixup============input==============" << input;
    47. //这里要做个判断,低于最小值取最小值,例如0.01转换为0.02,
    48. double value = input.toDouble();
    49. if(value < bottom())
    50. input = QString("%1").arg(bottom());
    51. }

     

    完整代码如下:

    1. #ifndef MAINWINDOW_H
    2. #define MAINWINDOW_H
    3. #include
    4. QT_BEGIN_NAMESPACE
    5. namespace Ui { class MainWindow; }
    6. QT_END_NAMESPACE
    7. class MainWindow : public QMainWindow
    8. {
    9. Q_OBJECT
    10. public:
    11. MainWindow(QWidget *parent = nullptr);
    12. ~MainWindow();
    13. void initView();
    14. private:
    15. Ui::MainWindow *ui;
    16. };
    17. #endif // MAINWINDOW_H
    1. #include "mainwindow.h"
    2. #include "ui_mainwindow.h"
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include "customintvalidator.h"
    8. #include "customdoublevalidator.h"
    9. MainWindow::MainWindow(QWidget *parent)
    10. : QMainWindow(parent)
    11. , ui(new Ui::MainWindow)
    12. {
    13. ui->setupUi(this);
    14. initView();
    15. }
    16. MainWindow::~MainWindow()
    17. {
    18. delete ui;
    19. }
    20. void MainWindow::initView()
    21. {
    22. QRegExp regIntExp("^(([1-9][0-9]|[1-9])|100)$");
    23. QValidator *regIntValidator = new QRegExpValidator(regIntExp, ui->lineEdit);
    24. ui->lineEdit->setValidator(regIntValidator);
    25. //1-100整数
    26. QIntValidator *intValidator = new QIntValidator(1, 100, this);
    27. intValidator->setRange(1, 100);
    28. ui->lineEdit_2->setValidator(intValidator);
    29. //1-100整数
    30. CustomIntValidator *customIntValidator = new CustomIntValidator(1, 100, this);
    31. customIntValidator->setRange(1, 100);
    32. ui->lineEdit_3->setValidator(customIntValidator);
    33. // 0.01-100.0 大于0的浮点数
    34. QRegExp regExp("^(([1-9][0-9]|[1-9])(\\.\\d{1,2})?|0\\.\\d{1,2}|100)$");
    35. QValidator *validator = new QRegExpValidator(regExp, ui->lineEdit_4);
    36. ui->lineEdit_4->setValidator(validator);
    37. // 0.02-100.0 大于0的浮点数
    38. QDoubleValidator *doubleValidator = new QDoubleValidator(this);
    39. doubleValidator->setRange(0.02, 100.0, 2);
    40. doubleValidator->setNotation(QDoubleValidator::StandardNotation);
    41. ui->lineEdit_5->setValidator(doubleValidator);
    42. CustomDoubleValidator *customDoubleValidator = new CustomDoubleValidator(this);
    43. customDoubleValidator->setRange(0.02, 100.0, 2);
    44. customDoubleValidator->setNotation(QDoubleValidator::StandardNotation);
    45. ui->lineEdit_6->setValidator(customDoubleValidator);
    46. }

    运行结果:

    参考:
    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

  • 相关阅读:
    linux oracle 2022年10月份补丁集:11.2.0.4.221018 PSU补丁包已发布,包含 database,ojvm和GI
    为什么 BI 软件都搞不定关联分析
    具体的多路分发器:EPollPoller
    网站开启HTTPS,免费的 SSL证书 申请渠道有哪些?
    Windows桌面自动化测试工具:WinAppDriver
    C#常用多线程(线程同步,事件触发,信号量,互斥锁,共享内存,消息队列)
    MFC Windows 程序设计[214]之对话框样式修改例程(附源码)
    Oracle/PLSQL: Rank Function
    微服务保护--Sentinel
    水塘抽样(应用场景+算法步骤+算法证明+Python实现)
  • 原文地址:https://blog.csdn.net/chenyijun/article/details/133255915