how to convert QBytearray to QString? - qt

now I have a QByteArray object, I need to convert it to QString and print the content in HEX format. But I don't find correct method.
`QByteArray serial;
serial.resize(4);
serial[0] = 0xA0;
serial[1] = 0x01;
serial[2] = 0x05;
serial[3] = 0xA6;`
QString str = "how to convert serial to QString"
convert "serial" object to QString object and the print format is "0xA0 0x01 0x05 0xA6"

Hope this one-liner solution will be useful:
auto str = QString("0x%1").arg(QString(serial.toHex(':').toUpper())).replace(":"," 0x");

Related

How can i convert a QByteArray into a hex string?

I have the blow QByteArray.
QByteArray ba;
ba[0] = 0x01;
ba[1] = 0x10;
ba[2] = 0x00;
ba[3] = 0x07;
I have really no idea how to convert this QByteArray into resulted string which have "01100007", which i would use the QRegExp for pattern matching on this string?
First of all, the QByteArray does not contain "hex values", it contains bytes (as it's name implies). Number can be "hex" only when it is printed as text.
Your code should be:
QByteArray ba(4, 0); // array length 4, filled with 0
ba[0] = 0x01;
ba[1] = 0x10;
ba[2] = 0x00;
ba[3] = 0x07;
Anyway, to convert a QByteArray to a hex string, you got lucky: just use QByteArray::toHex() method!
QByteArray ba_as_hex_string = ba.toHex();
Note that it returns 8-bit text, but you can just assign it to a QString without worrying much about encodings, since it is pure ASCII. If you want upper case A-F in your hexadecimal numbers instead of the default a-f, you can use QByteArray::toUpper() to convert the case.
QString has following contructor:
constructor QString(const QByteArray &ba)
But note that an octal number is preceeded by 0 in c++, so some of your values are deciamal, some octal, none of them are hex.

Construct a QByteArray from a HEX value entered as a QString

If QString str = "0xFFFF", how to turn this text representation of an hex into a QByteArray? In the end, I would like to have the same of what I get from the following:
QByteArray ba;
ba.resize(2);
ba[0] = 0xFF;
ba[1] = 0xFF;
In either case the final QByteArray would be a sequence of hex values, i.e. FFFF. Conversion should be applied on that string. Given that, if your input string is provided prepended with the 0x, you should get rid of it via mid().
Here is a code snippet which compares the results of the two approaches: manually filling the QByteArray with hex values or converting hex values from a QString:
QByteArray array1;
array1.resize(2);
array1[0] = 0xFF;
array1[1] = 0xFF;
QString str = "0xFFFF";
QString value = str.mid(2); // "FFFF" <- just the hex values!
QByteArray array2 = QByteArray::fromHex(value.toLatin1());
qDebug() << array1; // not printable chars
qDebug() << array2;
qDebug() << array1.toHex(); // to have a printable form use "toHex()"!
qDebug() << array2.toHex();

QString to unicode std::string

I know there is plenty of information about converting QString to char*, but I still need some clarification in this question.
Qt provides QTextCodecs to convert QString (which internally stores characters in unicode) to QByteArray, allowing me to retrieve char* which represents the string in some non-unicode encoding. But what should I do when I want to get a unicode QByteArray?
QTextCodec* codec = QTextCodec::codecForName("UTF-8");
QString qstr = codec->toUnicode("Юникод");
std::string stdstr(reinterpret_cast<const char*>(qstr.constData()), qstr.size() * 2 ); // * 2 since unicode character is twice longer than char
qDebug() << QString(reinterpret_cast<const QChar*>(stdstr.c_str()), stdstr.size() / 2); // same
The above code prints "Юникод" as I've expected. But I'd like to know if that is the right way to get to the unicode char* of the QString. In particular, reinterpret_casts and size arithmetics in this technique looks pretty ugly.
The below applies to Qt 5. Qt 4's behavior was different and, in practice, broken.
You need to choose:
Whether you want the 8-bit wide std::string or 16-bit wide std::wstring, or some other type.
What encoding is desired in your target string?
Internally, QString stores UTF-16 encoded data, so any Unicode code point may be represented in one or two QChars.
Common cases:
Locally encoded 8-bit std::string (as in: system locale):
std::string(str.toLocal8Bit().constData())
UTF-8 encoded 8-bit std::string:
str.toStdString()
This is equivalent to:
std::string(str.toUtf8().constData())
UTF-16 or UCS-4 encoded std::wstring, 16- or 32 bits wide, respectively. The selection of 16- vs. 32-bit encoding is done by Qt to match the platform's width of wchar_t.
str.toStdWString()
U16 or U32 strings of C++11 - from Qt 5.5 onwards:
str.toStdU16String()
str.toStdU32String()
UTF-16 encoded 16-bit std::u16string - this hack is only needed up to Qt 5.4:
std::u16string(reinterpret_cast<const char16_t*>(str.constData()))
This encoding does not include byte order marks (BOMs).
It's easy to prepend BOMs to the QString itself before converting it:
QString src = ...;
src.prepend(QChar::ByteOrderMark);
#if QT_VERSION < QT_VERSION_CHECK(5,5,0)
auto dst = std::u16string{reinterpret_cast<const char16_t*>(src.constData()),
src.size()};
#else
auto dst = src.toStdU16String();
If you expect the strings to be large, you can skip one copy:
const QString src = ...;
std::u16string dst;
dst.reserve(src.size() + 2); // BOM + termination
dst.append(char16_t(QChar::ByteOrderMark));
dst.append(reinterpret_cast<const char16_t*>(src.constData()),
src.size()+1);
In both cases, dst is now portable to systems with either endianness.
Use this:
QString Widen(const std::string &stdStr)
{
return QString::fromUtf8(stdStr.data(), stdStr.size());
}
std::string Narrow(const QString &qtStr)
{
QByteArray utf8 = qtStr.toUtf8();
return std::string(utf8.data(), utf8.size());
}
In all cases you should have utf8 in std::string.
You can get the QByteArray from a UTF-16 encoded QString using this:
QTextCodec *codec = QTextCodec::codecForName("UTF-16");
QTextEncoder *encoderWithoutBom = codec->makeEncoder( QTextCodec::IgnoreHeader );
QByteArray array = encoderWithoutBom->fromUnicode( str );
This way you ignore the unicode byte order mark (BOM) at the beginning.
You can convert it to char * like:
int dataSize=array.size();
char * data= new char[dataSize];
for(int i=0;i<dataSize;i++)
{
data[i]=array[i];
}
Or simply:
char *data = array.data();

Serial port communication in Qt

I am new to Qt and need to prepare a project to send hex commands from rs232.
QString line contains 64bit binary data which i have to convert into hexadecimal and send it through rs232 .
QString a=ui->comboBox->currentText();
QString s1;
s1="./calc "+a;
QProcess p1;
p1.start(s1);
p1.waitForFinished(-1);
QString line ;
//read
QFile file("TeleOutput.txt");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
QTextStream in (&file);
line = in.readAll();
ui->plainTextEdit->setPlainText(line);
So, how to convert 64 bit binary data in QString line to hexadecimal value and transfer it through rs232?
First of all - you should really use QtSerialPort
Second of all - QString is a class, which works with actual string. QByteArray works with raw data. When you write QString line = in.readAll(); it implicitly calls QString(const QByteArray &ba), which uses QString::fromAscii.
Last of all, if you want to process 64bit integers, you should do something like this:
quint64 d;
QDataStream stream(&file);
while (!stream.atEnd())
{
stream >> d;
process(d);
}
Update
Quote:
My problem is that in plainTextEdit
"1111110101000101010101010101010101010101010101010101010......." 64
bit data is populated , i need to convert this data into hex and send it through rs232
Solution:
QString binData = plainTextEdit.toPlainText();
QByteArray result;
while (binData.size() >= 64)
{
quint64 d;
QString dataPiece = binData.left(64);
binData.remove(0, 64);
d = dataPiece.toULongLong(0, 2);
result += QByteArray::number(d);
}
_com->write(result);
_com->flush();
Where _com is a pointer to QtSerialPort, with all parameters set and opened without errors.

QByteArray to integer

As you may have figured out from the title, I'm having problems converting a QByteArray to an integer.
QByteArray buffer = server->read(8192);
QByteArray q_size = buffer.mid(0, 2);
int size = q_size.toInt();
However, size is 0. The buffer doesn't receive any ASCII character and I believe the toInt() function won't work if it's not an ASCII character. The int size should be 37 (0x25), but - as I have said - it's 0.
The q_size is 0x2500 (or the other endianness order - 0x0025).
What's the problem here ? I'm pretty sure q_size holds the data I need.
Something like this should work, using a data stream to read from the buffer:
QDataStream ds(buffer);
short size; // Since the size you're trying to read appears to be 2 bytes
ds >> size;
// You can continue reading more data from the stream here
The toInt method parses a int if the QByteArray contains a string with digits. You want to interpret the raw bits as an integer. I don't think there is a method for that in QByteArray, so you'll have to construct the value yourself from the single bytes. Probably something like this will work:
int size = (static_cast<unsigned int>(q_size[0]) & 0xFF) << 8
+ (static_cast<unsigned int>(q_size[1]) & 0xFF);
(Or the other way around, depending on Endianness)
I haven't tried this myself to see if it works but it looks from the Qt docs like you want a QDataStream. This supports extracting all the basic C++ types and can be created wth a QByteArray as input.
bool ok;
q_size.toHex().toInt(&ok, 16);
works for me
I had great problems in converting serial data (QByteArray) to integer which was meant to be used as the value for a Progress Bar, but solved it in a very simple way:
QByteArray data = serial->readall();
QString data2 = tr(data); //converted the byte array to a string
ui->QProgressBar->setValue(data2.toUInt()); //converted the string to an unmarked integer..
This works for me:
QByteArray array2;
array2.reserve(4);
array2[0] = data[1];
array2[1] = data[2];
array2[2] = data[3];
array2[3] = data[4];
memcpy(&blockSize, array2, sizeof(int));
data is a qbytearray, from index = 1 to 4 are array integer.
Create a QDataStream that operates on your QByteArray. Documentation is here
Try toInt(bool *ok = Q_NULLPTR, int base = 10) const method of QByteArray Class.
QByteArray Documentatio: http://doc.qt.io/qt-5/QByteArray.html

Resources