Set QLineEdit to accept only numbers

123,397

Solution 1

QLineEdit::setValidator(), for example:

myLineEdit->setValidator( new QIntValidator(0, 100, this) );

or

myLineEdit->setValidator( new QDoubleValidator(0, 100, 2, this) );

See: QIntValidator, QDoubleValidator, QLineEdit::setValidator

Solution 2

The best is QSpinBox.

And for a double value use QDoubleSpinBox.

QSpinBox myInt;
myInt.setMinimum(-5);
myInt.setMaximum(5);
myInt.setSingleStep(1);// Will increment the current value with 1 (if you use up arrow key) (if you use down arrow key => -1)
myInt.setValue(2);// Default/begining value
myInt.value();// Get the current value
//connect(&myInt, SIGNAL(valueChanged(int)), this, SLOT(myValueChanged(int)));

Solution 3

The Regex Validator

So far, the other answers provide solutions for only a relatively finite number of digits. However, if you're concerned with an arbitrary or a variable number of digits you can use a QRegExpValidator, passing a regex that only accepts digits (as noted by user2962533's comment). Here's a minimal, complete example:

#include <QApplication>
#include <QLineEdit>
#include <QRegExpValidator>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QLineEdit le;
    le.setValidator(new QRegExpValidator(QRegExp("[0-9]*"), &le));
    le.show();

    return app.exec();
}

The QRegExpValidator has its merits (and that's only an understatement). It allows for a bunch of other useful validations:

QRegExp("[1-9][0-9]*")    //  leading digit must be 1 to 9 (prevents leading zeroes).
QRegExp("\\d*")           //  allows matching for unicode digits (e.g. for 
                          //    Arabic-Indic numerals such as ٤٥٦).
QRegExp("[0-9]+")         //  input must have at least 1 digit.
QRegExp("[0-9]{8,32}")    //  input must be between 8 to 32 digits (e.g. for some basic
                          //    password/special-code checks).
QRegExp("[0-1]{,4}")      //  matches at most four 0s and 1s.
QRegExp("0x[0-9a-fA-F]")  //  matches a hexadecimal number with one hex digit.
QRegExp("[0-9]{13}")      //  matches exactly 13 digits (e.g. perhaps for ISBN?).
QRegExp("[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}")
                          //  matches a format similar to an ip address.
                          //    N.B. invalid addresses can still be entered: "999.999.999.999".     

More On Line-edit Behaviour

According to documentation:

Note that if there is a validator set on the line edit, the returnPressed()/editingFinished() signals will only be emitted if the validator returns QValidator::Acceptable.

Thus, the line-edit will allow the user to input digits even if the minimum amount has not yet been reached. For example, even if the user hasn't inputted any text against the regex "[0-9]{3,}" (which requires at least 3 digits), the line-edit still allows the user to type input to reach that minimum requirement. However, if the user finishes editing without satsifying the requirement of "at least 3 digits", the input would be invalid; the signals returnPressed() and editingFinished() won't be emitted.

If the regex had a maximum-bound (e.g. "[0-1]{,4}"), then the line-edit will stop any input past 4 characters. Additionally, for character sets (i.e. [0-9], [0-1], [0-9A-F], etc.) the line-edit only allows characters from that particular set to be inputted.

Note that I've only tested this with Qt 5.11 on a macOS, not on other Qt versions or operating systems. But given Qt's cross-platform schema...

Demo: Regex Validators Showcase

Solution 4

You could also set an inputMask:

QLineEdit.setInputMask("9")

This allows the user to type only one digit ranging from 0 to 9. Use multiple 9's to allow the user to enter multiple numbers. See also the complete list of characters that can be used in an input mask.

(My answer is in Python, but it should not be hard to transform it to C++)

Solution 5

Why don't you use a QSpinBox for this purpose ? You can set the up/down buttons invisible with the following line of codes:

// ...
QSpinBox* spinBox = new QSpinBox( this );
spinBox->setButtonSymbols( QAbstractSpinBox::NoButtons ); // After this it looks just like a QLineEdit.
//...
Share:
123,397
sashoalm
Author by

sashoalm

Updated on August 08, 2020

Comments

  • sashoalm
    sashoalm almost 4 years

    I have a QLineEdit where the user should input only numbers.

    So is there a numbers-only setting for QLineEdit?

  • sashoalm
    sashoalm about 10 years
    Can this be done from Qt Designer, or is it possible only through code?
  • Chris
    Chris about 10 years
    To my knowledge there is no way to do this in designer.
  • DrHaze
    DrHaze about 9 years
    Even if the OP wants to work with a QLineEdit, using a QSpinBox is definitely the best approach.
  • Frederik Aalund
    Frederik Aalund over 8 years
    This is a quick solution if you need input given in scientific notation (e.g., 3.14e-7). QDoubleSpinBox does not not accept numbers in scientific notation (Qt 5.5).
  • McLan
    McLan over 8 years
    If i put (1,100), it will still accept 0 as an input. Besides, I can write 0 indefinitely (not just three times) !!
  • Steve
    Steve almost 8 years
    This works when the number range is small. Think about that you might want to use this widget for ages or id.
  • user2962533
    user2962533 almost 8 years
    See also QRegExpValidator with QRegExp("[0-9]*").
  • Alexandros
    Alexandros almost 8 years
    Your constructor invocation should be new QIntValidator(this), otherwise the validator object will leak as soon as your widget goes out of scope.
  • Micka
    Micka almost 8 years
    any way to make the spinbox more keyboard friendly to work with only number keys, decimal separator and backspace?
  • fmc
    fmc over 4 years
    Still works like a champ in 2020 =) Don't forget to add the include <QIntValidator>.
  • JuicyKitty
    JuicyKitty almost 4 years
    sorry for dumb question, but how memory of this validator will be released? Is it done by qt?
  • s_diaconu
    s_diaconu over 3 years
    @Chris QDoubleValidator works perfectly when you don't know how big is the integer, it stops only when you input second decimal.
  • Michael
    Michael about 3 years
    Note that NoButons doesn't actually remove the buttons, it just makes them the same color as the background of the QSpinBox. So in certain styles where the arrows are large, you'll have an annoyingly larger part of the QSpinBox that just looks blank and squishes the rest of the input field
  • Caglayan DOKME
    Caglayan DOKME over 2 years
    I've added the suggested line to the constructor of my MainWindow class, and it works brilliantly :)