I want to take 20 byte hex input from QlinEdit
and I want to validate QlinEdit
for only 20 bytes and also store it into QString
.
I have Done for trial purpose :
ui->SetValue->setMaxLength(4);
ui->SetValue->setInputMask("Hh hh hh hh");
But It is giving me 11 bytes instead of 4 bytes.
and the hex values are not coming in pair in QString
. What Should I do?
I have tried everything but I'm not able to do that.
I have used:
ui->SetValue->setInputMask("Hh hh hh hh");
else if (ui->checkBox_HEX->isChecked())
{
ui->SetValue->setEnabled(true);
obj = ui->SetValueUniqueId->text();
QByteArray bytes = obj.toLatin1();
int length = myHexArray.size(); //Number of bytes
printf("Number Of bytes = %d", length);
memcpy(buffer, obj.toStdString().c_str(), obj.size());
As I never used QLineEdit::setInputMask()
before, I made an MCVE – to provide an answer as well as for my own entertainment.
There are two essential parts in this sample:
qTxtIn.setInputMask(
QString::fromLatin1(
"HH HH HH HH HH HH HH HH HH HH HH HH HH HH HH HH HH HH HH HH"));
sets the input mask of QLineEdit
to accept 20 × 2 characters for which "Hexadecimal character required. A-F, a-f, 0-9." (Remember, one byte → two hex digits.)
(Note that h
in opposition permits hex digits but does not require.)
The other part is in the lambda which I used as signal handler to convert the hex digit input into the corresponding byte values:
QByteArray bytes = QByteArray::fromHex(text.toLatin1());
Thereby, text
is a QString
with the current text of the QLineEdit qTxtIn
(the signal sender). (Alternatively, I could have used qTxtIn.text()
.) QString
uses internally some kind of Unicode encoding (on Windows probably UTF-16).
The QByteArray::fromHex()
can interprete text input decoding hex-digits to byte values. The only issue – it expects a QByteArray
as input.
Therefore, the QString
is converted to QByteArray
(before applied to QByteArray::fromHex()
) using the method QString::toLatin1()
. Consider, that Latin1 provides much less characters than Unicode. However, in the case of hex-digits this really is no problem as the digits 0 ... 9 as well as the letters a ... f (and A ... F) are available in Latin1 also.
The rest is what I considered entertainment – in my case converting the bytes to a C string to make them printable again.
The complete sample code testQLineEdit-Hex.cc
:
#include <QtWidgets>
typedef unsigned char uchar;
int main(int argc, char **argv)
{
// build appl.
qDebug() << "Qt Version: " << QT_VERSION_STR;
QApplication app(argc, argv);
// build GUI
QWidget qMainWin;
QGridLayout qGrid;
QLabel qLblIn(QString::fromUtf8("Input (20 hex bytes):"));
qGrid.addWidget(&qLblIn, 0, 0);
QLineEdit qTxtIn;
qTxtIn.setInputMask(
QString::fromLatin1(
"HH HH HH HH HH HH HH HH HH HH HH HH HH HH HH HH HH HH HH HH"));
qGrid.addWidget(&qTxtIn, 0, 1);
QLabel qLblOut(QString::fromUtf8("Output (C string):"));
qGrid.addWidget(&qLblOut, 1, 0);
QLineEdit qTxtOut;
qTxtOut.setReadOnly(true);
qGrid.addWidget(&qTxtOut, 1, 1);
qMainWin.setLayout(&qGrid);
qMainWin.show();
// install signal handlers
QObject::connect(&qTxtIn, &QLineEdit::textEdited,
[&qTxtOut](const QString &text) {
// get bytes from input
QByteArray bytes = QByteArray::fromHex(text.toLatin1());
// encode bytes as C String
QString textOut;
for (const char c : bytes) {
switch (c) {
case '\"': textOut += QString::fromLatin1("\\\""); break;
case '\a': textOut += QString::fromLatin1("\\a"); break;
case '\b': textOut += QString::fromLatin1("\\b"); break;
case '\f': textOut += QString::fromLatin1("\\f"); break;
case '\n': textOut += QString::fromLatin1("\\n"); break;
case '\r': textOut += QString::fromLatin1("\\r"); break;
case '\t': textOut += QString::fromLatin1("\\t"); break;
case '\v': textOut += QString::fromLatin1("\\v"); break;
case '\\': textOut += QString::fromLatin1("\\\\"); break;
default:
if (c >= ' ' && c < '\x7f') textOut += c;
else textOut += QString("\\%1").arg((int)(uchar)c, 3, 8, QChar('0'));
}
}
qTxtOut.setText(textOut);
});
// exec. application
return app.exec();
}
I compiled and tested in VS2013 with Qt 5.9.2 on Windows 10 (64 bit):
As you can see, I praticed my memory about ASCII values...