Abhishek Agarwal
Abhishek Agarwal

Reputation: 1248

Qt remove character from QLineEdit if its not hexadecimal

I have a QLineEdit in my Qt application which needs to take a hexadecimal value as an input. I want the application to display a warning Message box if the character entered is not hexadecimal and delete the invalid character from the QLineEdit. This check has to be performed at the entry of each character in the QLineEdit. So far I have got this:

void MemoryTestWindow::on_lineEditAddress1_textChanged(const QString &arg1)
{
        QString text1=ui->lineEditAddress1->text();
        int len=text1.length();
        QChar ch=text1.at(len-1).toUpper();
        if(!((ch>='A'&& ch<='F')|| (ch>='0' && ch<='9')))
        {
            text1.remove(len-1,1);
            //*arg1="";
            QMessageBox::warning(this,"Invalid Character!","Please enter hexadecimal characters 0-9, A-F");

        }

} 

I am using the textChanged slot of the QLineEdit since I need to perform the check after each character entry. I can't figure how to change the value in QLineEdit i.e. the last invalid character should be deleted after clicking 'OK' in the warning Message box. How can I do this?

Upvotes: 2

Views: 2651

Answers (3)

Benjamin T
Benjamin T

Reputation: 8311

The standard way to do this is to use a QValidator

 QRegExpValidator *v = new QRegExpValidator("[a-fA-F0-9]*", this); // or QRegularExpressionValidator
 ui->lineEdit->setValidator(v);

As QValidator inherits QObject you can make it emit a signal to detect when the user type an invalid character:

class Validator : public QRegExpValidator
{
    Q_OBJECT
    public:
        Validator(const QRegExp &rx, QObject *parent = nullptr) : 
            QRegExpValidator(rx, parent)
        {}

        State validate(QString &input, int &pos) const override
        {
            State state = QRegExpValidator::validate(input, pos);
            if (state == Invalid)
                emit error();
            return state;
        }
    signals:
        void error();
}

And then you just have to connect to error() to show the error to the user:

 Validator *v = new Validator ("[a-fA-F0-9]*", this);
 ui->lineEdit->setValidator(v);
 connect(v, &Validator::error, this, &MyClass::handleWrongInput); 
 // Where handleWrongInput is the slot that handles the error and eventually show an error message

Addendum

If in MyClass::handleWrongInput(), you do something that causes the QLineEdit to recall QValidator::validate(), like changing the keyboard focus, you will create a loop as the first call to validate() still has not returned. To fix this, you should let the call to validate() return before calling MyClass::handleWrongInput().

To do so the easiest solution is to use queued connection:

connect(v, &Validator::error, this, &MyClass::handleWrongInput, Qt::QueuedConnection);

Upvotes: 3

Antwane
Antwane

Reputation: 22688

Don't reinvent the wheel ;) You will probably have better results using the Qt tools designed to achieve what you want.

QLineEdit::mask let you define what characters are allowed in your edit control. In particular, defining a mask using H chars will let you determine how many hexadecimal characters are allowed in the control.

If this is not enough to what you want to do, looks around validators for more complex and complete validation process.

Upvotes: 5

Adrian Kielijan
Adrian Kielijan

Reputation: 82

What about using ui->lineEditAddress1->setText(text1.remove(len-1, 1))? Also, not sure if that has any chance to work, but maybe backspace() method will work just fine?

http://doc.qt.io/qt-4.8/qlineedit.html#backspace

Upvotes: 1

Related Questions