Unable to take a 20 byte hex input from Qlinedit a

2019-03-01 17:58发布

问题:

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());

回答1:

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...



标签: c++ qt qt4