Wonky behavior of QLineEdit with inputmask -- cursor in wrong position
-
I'm using Qt 5.14 (customer requirement).
I posted a similar question, but never really got a resolution other than "that's the way Qt does it."
I have a QLineEdit with an inputmask of HHHHHHHH. The cursor is in the wrong position. Here is a detailed example.
Initial state:
Here is the state after pressing the backspace key once.
The expected behavior would be to delete the character "B", and not the character "D".
The next screenshot is after input of the letter "A"
This is not going to be OK with my customer. How do I fix it?
-
@SGaist Since you asked about the font, I tried some other fonts. Same result.
If, however, I remove the input mask (no mask), the wonky behavior goes away. But then, so does the check for a hex character on each keystroke. BTW, the same problem occurs with an input mask for binary input ("BBBBBBBB....").
That may be the only practical solution. Although I'd rather not have to tell the customer that Qt's inputmask feature doesn't work.
I think I have an acceptable solution using a QValidator.
In the #include:
#include <QRegularExpression> class HexValidator : public QValidator { QValidator::State validate(QString &input, int & /*pos*/) const; };
In the cpp file:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) , hv(new HexValidator) { ui->setupUi(this); ui->lineEdit->setValidator(hv); } QValidator::State HexValidator::validate(QString &input, int & /*pos*/) const { QValidator::State valid(QValidator::Invalid); QRegularExpression re(QRegularExpression::anchoredPattern("[0-9A-F]*")); //hex digit, uppercase only QRegularExpressionMatch match = re.match(input); bool matched = match.hasMatch(); if(matched) { valid = QValidator::Acceptable; } return valid; }
Similar solution for binary input validation.
Probably will need some tweaking, but that appears to work in my simplified example project. Plus, the inputmask wonkiness is gone.
-
Hi,
Can you provide a minimal compilable example that shows this behaviour ?
Also which font are you using ?
-
Hi,
Can you provide a minimal compilable example that shows this behaviour ?
Also which font are you using ?
@SGaist Ok, here goes: New project with C++. Added one QLineEdit to mainwindow.
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); } MainWindow::~MainWindow() { delete ui; }
Main window with one QLineEdit
Font: MS Shell Dlg 2, 8
Kit: Desktop Qt 5.14.2 MinGW 32-bit (same results with 64 bit)
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>MainWindow</class> <widget class="QMainWindow" name="MainWindow"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>263</width> <height>160</height> </rect> </property> <property name="windowTitle"> <string>MainWindow</string> </property> <widget class="QWidget" name="centralwidget"> <widget class="QLineEdit" name="lineEdit"> <property name="geometry"> <rect> <x>70</x> <y>50</y> <width>113</width> <height>21</height> </rect> </property> <property name="inputMask"> <string>HHHHHHHH</string> </property> <property name="text"> <string>DEADBEEF</string> </property> </widget> </widget> <widget class="QMenuBar" name="menubar"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>263</width> <height>21</height> </rect> </property> </widget> <widget class="QStatusBar" name="statusbar"/> </widget> <resources/> <connections/> </ui>
Run:
Position Cursor:
Press Backspace Key:
Enter "A"
-
@SGaist Ok, here goes: New project with C++. Added one QLineEdit to mainwindow.
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); } MainWindow::~MainWindow() { delete ui; }
Main window with one QLineEdit
Font: MS Shell Dlg 2, 8
Kit: Desktop Qt 5.14.2 MinGW 32-bit (same results with 64 bit)
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>MainWindow</class> <widget class="QMainWindow" name="MainWindow"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>263</width> <height>160</height> </rect> </property> <property name="windowTitle"> <string>MainWindow</string> </property> <widget class="QWidget" name="centralwidget"> <widget class="QLineEdit" name="lineEdit"> <property name="geometry"> <rect> <x>70</x> <y>50</y> <width>113</width> <height>21</height> </rect> </property> <property name="inputMask"> <string>HHHHHHHH</string> </property> <property name="text"> <string>DEADBEEF</string> </property> </widget> </widget> <widget class="QMenuBar" name="menubar"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>263</width> <height>21</height> </rect> </property> </widget> <widget class="QStatusBar" name="statusbar"/> </widget> <resources/> <connections/> </ui>
Run:
Position Cursor:
Press Backspace Key:
Enter "A"
@SGaist Since you asked about the font, I tried some other fonts. Same result.
If, however, I remove the input mask (no mask), the wonky behavior goes away. But then, so does the check for a hex character on each keystroke. BTW, the same problem occurs with an input mask for binary input ("BBBBBBBB....").
That may be the only practical solution. Although I'd rather not have to tell the customer that Qt's inputmask feature doesn't work.
-
@SGaist Since you asked about the font, I tried some other fonts. Same result.
If, however, I remove the input mask (no mask), the wonky behavior goes away. But then, so does the check for a hex character on each keystroke. BTW, the same problem occurs with an input mask for binary input ("BBBBBBBB....").
That may be the only practical solution. Although I'd rather not have to tell the customer that Qt's inputmask feature doesn't work.
I think I have an acceptable solution using a QValidator.
In the #include:
#include <QRegularExpression> class HexValidator : public QValidator { QValidator::State validate(QString &input, int & /*pos*/) const; };
In the cpp file:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) , hv(new HexValidator) { ui->setupUi(this); ui->lineEdit->setValidator(hv); } QValidator::State HexValidator::validate(QString &input, int & /*pos*/) const { QValidator::State valid(QValidator::Invalid); QRegularExpression re(QRegularExpression::anchoredPattern("[0-9A-F]*")); //hex digit, uppercase only QRegularExpressionMatch match = re.match(input); bool matched = match.hasMatch(); if(matched) { valid = QValidator::Acceptable; } return valid; }
Similar solution for binary input validation.
Probably will need some tweaking, but that appears to work in my simplified example project. Plus, the inputmask wonkiness is gone.
-
Hi, I have the same problem (wonky behavior) with a QLineEdit with a mask for inputting social security numbers.
Using a ->setValidator() seems like the better stuff, thank you for posting the code!@hskoglund I'm glad I could help!
It definitely appears to me that the inputmask "feature" is broken, and custom validators is the way to go.