Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. My fix for the strange behaviour of QValidator.

My fix for the strange behaviour of QValidator.

Scheduled Pinned Locked Moved Solved General and Desktop
1 Posts 1 Posters 246 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    ntos
    wrote on last edited by
    #1

    I was going to ask a question about QIntValidator strange behaviour of allowing you to enter a number larger than the max value when I knew I had to search for an answer on this forum first. No solution could be found. Anyway, with the help of chatgpt I have come up with a solution. people here have helped me so I think it may help beginners like me to post the solution here:
    P.S. If this is not appropriate, please delete this post. Thank you very much.

    #include "MainWindow.h"
    #include "ui_MainWindow.h"
    #include <QIntValidator>
    #include <QDoubleValidator>
    #include <QLineEdit>
    #include <QGridLayout>
    #include <QLabel>
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        this->setGeometry(50, 50, 120, 50);
        QGridLayout* layout = new QGridLayout();
        QLineEdit* intEdit = new QLineEdit("0");
        QLineEdit* doubleEdit = new QLineEdit("0.0");
        layout->addWidget(new QLabel("Enter an integer: "), 0, 0);
        // second pair: 1, 2 means row occupies 1 row, 2 means col occupies 2 cols.
        layout->addWidget(intEdit, 0, 1, 1, 2);
        layout->addWidget(new QLabel("Enter a double: "), 1, 0);
        layout->addWidget(doubleEdit, 1, 1, 1, 2);
    
        QIntValidator* intValidator = new QIntValidator(-50, 100);
       // intValidator->setRange(0, 100); // we can use this.
        intEdit->setValidator(intValidator);
        QString* previousValidValue = new QString(intEdit->text());
    
        // NOTE that we use the textChanged SIGNAL so that we can check each single input character in real time.
        connect(intEdit, &QLineEdit::textChanged, [intEdit, intValidator, previousValidValue] {
            QString valueStr = intEdit->text();
            int pos = 0; // Dummy variable needed by validate, but unused.
    
        // Note that only this IF CONDITION works. Nothing else will not work as expected.
        // A. if valueStr is not within bounds ( -50 =< valueStr <= 100), if returns true. So we call setText(previous_value) on intEdit.
        // To make this clear, suppose we enter 9, which is valid so the else clause runs and previousValidValue == 9.
        // We enter 9 again and intEdit now has 99 and valueStr = 99, valid and previousValidValue == 99. When we enter a third digit,
        // now intEdit contains 990 and if returns true and intEdit->setText(*previousValidValue); runs, which displays 99.
        // That's why we can never exceed 100.
        // B. if valueStr is within bounds, if returns false. So we update previousValidValue with the current valid input.
        // C. If we comment out the else clause, and enter a two-digit number more than once, we'll get 0 + the two-digit number.
        // 0 is our initial number given to the constructor of intEdit.
        // D. We cannot enter 1-0, i.e the minus sign after a digit. Great!
            if (intValidator->validate(valueStr, pos) != QValidator::Acceptable
                        && !valueStr.isEmpty()
                        && valueStr != "-")
            {
                intEdit->setText(*previousValidValue);
            } else {
                // Update previous valid value if current input is valid
                *previousValidValue = valueStr;
            }
        });
           // add layout to the central widget to be displayed.
        this->centralWidget()->setLayout(layout);
    
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    1 Reply Last reply
    0
    • N ntos has marked this topic as solved on

    • Login

    • Login or register to search.
    • First post
      Last post
    0
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Get Qt Extensions
    • Unsolved