I'm new in Qt and can't find any solution in Qt libraries.
I'd like to find smth without loop usage.
Is there any way to convert QByteArray to QString with - between bytes?
For example:
QByteArray = XX1F2C5A
QString = "XX-1F-2C-5A".
Yeah you can with QString::replace:
QByteArray b = "XX1F2C5A";
QString s(b);
qDebug() << s;
s.replace(QRegExp("(..)[^$]"), QString("\\1-"));
qDebug() << s;
Related
I am using some functions to convert QVector's to QByteArray's, for example:
QByteArray Serialize::serialize(QVector<double> data)
{
QByteArray byteArray;
QDataStream out(&byteArray, QIODevice::WriteOnly);
out << data;
return byteArray;
}
void Serialize::deserialize(QByteArray byteArray, QVector<double> *data)
{
QDataStream in(&byteArray, QIODevice::ReadOnly);
in >> *data;
}
Now, that I have the QByteArray I need to put it in a text file, how can I convert it to QString?
I already tried the simplest way:
QString myString(data); // data - QByteArray
But myString is always empty.
I also found the toStdString() function in the documentation, but it was introduced only in Qt 5.4.
I'm using Qt 5.3.
Follows a complete example:
#include <QCoreApplication>
#include <QDebug>
#include <QVector>
#include <QByteArray>
#include <QDataStream>
QByteArray serialize(QVector<double> data)
{
QByteArray byteArray;
QDataStream out(&byteArray, QIODevice::WriteOnly);
out << data;
return byteArray;
}
void deserialize(QByteArray byteArray, QVector<double> *data)
{
QDataStream in(&byteArray, QIODevice::ReadOnly);
in >> *data;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QVector<double> data;
data << 1.1 << 2.2 << 3.3 << 4.4 << 5.5 << 6.6 << 7.7 << 8.8 << 9.9;
QByteArray byteArray = serialize(data);
QVector<double> dataConverted;
deserialize(byteArray, &dataConverted);
qDebug() << "Data:";
qDebug() << data;
qDebug() << "ByteArray:";
QString test(byteArray);
qDebug() << test;
qDebug() << "Data Converted:";
qDebug() << dataConverted;
return a.exec();
}
Note: The general objective of this is to generate a SQL file with all content from the SQLite database. My double vector is converted to QByteArray and stored as BLOB into the database (using the serialize function). When I need to load it from the database I use the deserialize function to convert to a double vector again. Now I need to generate the SQL file with the data in the BLOB format, then I can directly import it into another database.
The problem is that a byte array is type-agnostic data type, it simply represents a collection of individual bytes in memory. In your example code you are creating the byte array from a vector of doubles, and then converting back to another vector of doubles. No problem.
However when you pass the byte array into the QString constructor, the QString is trying to interpret the byte array as data that represents a string, for example an array of ASCII character codes.
Some string classes might let you do this, and create an instance filled with garbage, however QString appears to be doing some basic error checking and helping you out by giving you an empty string.
As for some code to print out the contents of a byte array of doubles, the deserialize method you've provided is not too bad an example.
Use QTextCodec to convert from QByteArray to QString, here's an example from official docs:
QByteArray encodedString = "...";
QTextCodec *codec = QTextCodec::codecForName("KOI8-R");
QString string = codec->toUnicode(encodedString);
And to make the example work, you need to convert the doubles to QStrings during serialization:
QByteArray serialize(QVector<double> data)
{
QByteArray byteArray;
QDataStream out(&byteArray, QIODevice::WriteOnly);
for (double d : data) {
out << QString::number(d);
}
return byteArray;
}
If you don't want to convert individual numbers to string, you can also "stringify" the QByteArray with byteArray.toHex():
qDebug() << "ByteArray:";
QString test(byteArray.toHex());
I am using Qt (5.5) and I want to exchange data in JSON format in a client-server application.
So the format is constant:
{
"ball":
{
"posx": 12,
"posy": 35
}
}
I would like to be able to define a ByteArray or string like so:
QByteArray data = "{\"ball\":{\"posx\":%s,\"posy\":%s}}"
and then just write whatever the values for that into the string.
How do I do that?
QtJson is baked into Qt 5. It is easy to use, and gets it all ready for you pretty easily.
#include <QCoreApplication>
#include <QDebug>
#include <QJsonObject>
#include <QJsonDocument>
void saveToJson(QJsonObject & json);
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QJsonObject jsonObject;
saveToJson(jsonObject);
QJsonDocument jsonDoc(jsonObject);
qDebug() << "Example of QJsonDocument::toJson() >>>";
qDebug() << jsonDoc.toJson();
qDebug() << "<<<";
return a.exec();
}
void saveToJson(QJsonObject & json)
{
QJsonObject ball;
ball["posx"] = 12;
ball["posy"] = 35;
json["ball"] = ball;
}
output
Example of QJsonDocument::toJson() >>>
"{
"ball": {
"posx": 12,
"posy": 35
}
}
"
<<<
Note: qDebug() wraps QString objects in quotes when printing. To get rid of that, pass your QString into qPrintable(). And it puts endl in for you at the end of each line.
For a more complex example see the official:
JSON Save Game Example
http://doc.qt.io/qt-5/qtcore-json-savegame-example.html
Hope that helps.
And here are more examples of string manipulations, but for readability and maintainability, please use the QJson classes.
QString str;
str = QString("{\"ball\":{\"posx\":%1,\"posy\":%2}}").arg(12).arg(35);
qDebug() << qPrintable(str);
QByteArray ba = str.toLocal8Bit();
qDebug() << ba;
QString str2;
str2 = "{\"ball\":{\"posx\":"
+ QString::number(12)
+ ",\"posy\":"
+ QString::number(35)
+ "}}";
qDebug() << qPrintable(str2);
output
{"ball":{"posx":12,"posy":35}}
"{"ball":{"posx":12,"posy":35}}"
{"ball":{"posx":12,"posy":35}}
Note again that the quotes are added by qDebug() when printing a QByteArray object.
Hope that helps.
I am attempting to compare a QByteArray of an already saved html file with a QByteArray that was just downloaded. I have to convert the QString of the file's contents to QByteArray in order to compare them (or vice versa) and comparing bytes seems like the cleanest method, however when converted from QString to QByteArray, the size of the new QByteArray is smaller than what it should be. QByteArray QString::toLocal8Bit() const states that if it is undefined, the characters will be suppressed or replaced. It also said that it uses toLatin1() by default and tried to use ASCII since that is what a website is encoded in. I still get the same results.
bool NewsBulletin::compareDownload(QByteArray new_contents, QString filename)
{
bool return_what = false;
qDebug() << "I am in compareDownload";
// qDebug() << new_contents[1];
// qDebug() << new_contents[1] << endl
// << new_contents[2];
QFile file(application_path + filename);
if (file.exists())
{
// QString new_contents_qstr(new_contents);
file.open(QIODevice::ReadOnly | QIODevice::Text);
QTextStream in(&file);
QTextCodec::setCodecForLocale(QTextCodec::codecForName("ASCII"));
QString file_contents = in.readAll();
QByteArray file_byte_array = file_contents.toLocal8Bit();
qDebug() << "outputting new file array";
qDebug() << new_contents[5] << new_contents.size();
qDebug() << "outputting old file array";
qDebug() << file_byte_array[5] << file_byte_array.size();
for (int i=0; i<=file_byte_array.size(); i++)
{
if (file_byte_array[i] != new_contents[i])
{
return_what = true;
break;
}
else if (i == file_byte_array.size())
{
qDebug() << "compareDownload will return false, duplicate file.";
return_what = false;
}
}
}
else
{
qDebug() << "compareDownload will return true, DNE.";
return_what = true;
}
return return_what;
}
The output of the qDebug() from the function is:
I am in compareDownload
outputting new file array
T 64704
outputting old file array
T 64576
After reading the api for hours, I found the reason for the bytes being different.
file.open(QIODevice::ReadOnly | QIODevice::Text);
QIODevice::Text needs to be removed. This flag changes end of line terminators into the terminator for cpp, "\n", thus giving a byte difference.
I have a QUrl as this:
https://www.example.com/index.html#token=SomeToken&user=guest
and I want to obtain the value of the token i.e. SomeToken. I know about method QUrl::queryItemValue,so this code must work:
void MainWindow::get_token(QUrl url)
{
url = url.toString().replace("?","#");
QString token = url.queryItemValue("token");
}
but in Qt5 i can't use this method,how can I parse url?
There is new QUrlQuery class in Qt5. New QUrl doesn't support this method yet, so you should use QUrlQuery for parsing (it has this and other methods). Use
QUrlQuery query(url);
qDebug() << query.queryItemValue("token");
Note: be carefull with replace because QUrlQuery gives you correct result with
?token=SomeToken not a #token=SomeToken
http://qt-project.org/doc/qt-5/qurlquery.html
QUrlQuery queryItemValue method does not work properly in Qt 5.9 So i wrote my own function to parse GET parameters
#include <QCoreApplication>
#include <QUrlQuery>
#include <QDebug>
#include <QMap>
#include <QUrl>
QMap<QString,QString> ParseUrlParameters(QString &url)
{
QMap<QString,QString> ret;
if(url.indexOf('?')==-1)
{
return ret;
}
QString tmp = url.right(url.length()-url.indexOf('?')-1);
QStringList paramlist = tmp.split('&');
for(int i=0;i<paramlist.count();i++)
{
QStringList paramarg = paramlist.at(i).split('=');
ret.insert(paramarg.at(0),paramarg.at(1));
}
return ret;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QString url = "http://test1.ru/?token=test&email=test1";
QUrlQuery query(url);
qDebug() << "queryItemValue does not work in Qt 5.9.0 with dynamic QString" << query.queryItemValue("token") << "("<< endl;
qDebug() << "ParseUrlParameters(...) works fine..."<< endl;
QMapIterator<QString, QString> i(ParseUrlParameters(url));
while (i.hasNext())
{
i.next();
qDebug() << i.key() << ":" << i.value();
}
return a.exec();
}
I know this post is old but if my answer can help someone, I share :)
Tested under QT 5.15.2 and under QT 6.4.2
#include<QUrl>
#include<QUrlQuery>
#include<QDebug>
int main (int nbArg, char* listArg[])
{
// Initialization
QString myString = "https://www.factice.fr/demo.php?thing=123&subject=456&artificial=789";
QUrl myUrl(myString);
QUrlQuery myQuery(myUrl);
QMap<QString,QString> paramList; // Associative Array to Store Keys and Values
// For Each QPair
for(int i=0;i<myQuery.queryItems().size();i++)
{
// Information Display
qDebug() << myQuery.queryItems().at(i).first << " : " << myQuery.queryItems().at(i).second;
// Or Storage of Information for futur use
paramList.insert(myQuery.queryItems().at(i).first,myQuery.queryItems().at(i).second);
}
// End - For Each QPair
// Examples of Displaying Stored Information
qDebug() << paramList;
qDebug() << paramList["thing"];
}
I'm currently create an apps in Meego using QML and JS on most of the part. and now I stumbled upon a problem.
From javascript I want to call a C++ function to read text file, parse it, and then return an array of the parsing result.
so I create a Q_INVOKABLE function called parse() and call it through javascript
function parse() {
var myArray = new Array();
myArray = parser.parse("/home/user/MyDocs/angklungtext.txt")
if(myArray === undefined){
console.log("null found");
}
for(var i = 0; i < myArray.length; i++){
console.log(myArray[i][0] + "," + myArray[i][1])
}
}
and here is the parse function in C++
QVariantList* QMLParser::parse(QString filename)
{
qDebug() << "start debugging";
qDebug() << filename;
qDebug() << QDir::currentPath();
QDir dir;
qDebug()<< dir.absoluteFilePath(filename);
QFile file(filename);
if(!file.exists())
{
qDebug() << "File: " << file.fileName() << "tidak ditemukan";
return NULL;
}
if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
qDebug() << "Tidak dapat membuka file" << file.fileName() << "untuk ditulis";
return NULL;
}
QTextStream stream(&file);
QVariantList* myList = new QList<QVariant>;
while(!stream.atEnd())
{
QString line = stream.readLine();
qDebug() << line.trimmed();
QStringList lineList = line.split(":");
myList->append(lineList);
}
file.close();
return myList;
}
sadly.
when I try to run it it giving a result like this
start debugging
"/home/user/MyDocs/angklungtext.txt"
"/home/developer"
"/home/user/MyDocs/angklungtext.txt"
"1:1000"
"4:2000"
"5:3000"
"2:4000"
null found
file:///opt/memoryreader/qml/memoryreader/myjs.js:8: TypeError: Result of expression 'myArray' [undefined] is not an object.
looks like the C++ parse function successfully parsing the file. it can read it and it can save it into the QVariantList.
but after it return the result into javascript myArray still [undefined].
is there something wrong with the conversion?
Just simplify the C++ side like this :
QVariant QMLParser::parse(QString filename)
{
QStringList myList;
qDebug() << "start debugging";
qDebug() << filename;
qDebug() << QDir::currentPath();
QDir dir;
qDebug() << dir.absoluteFilePath(filename);
QFile file(filename);
if(!file.exists()) {
qDebug() << "File: " << file.fileName() << "tidak ditemukan";
return NULL;
}
if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug() << "Tidak dapat membuka file" << file.fileName() << "untuk ditulis";
return NULL;
}
QTextStream stream(&file);
while(!stream.atEnd()) {
QString line = stream.readLine();
qDebug() << line.trimmed();
myList << line.trimmed().split(":");
}
file.close();
return QVariant::fromValue(myList);
}
And it should work !
Just remember, QML must see a QVariant, even if a QList is wrapped inside it, and Qt is able to convert most of its base types to QVariant using QVariant::fromValue(T) so use it extensively.
Oh and BTW a QVariant is reference not pointer.
Haven't done this myself, so I'm just thinking out loud. But I note that you're returning a pointer to a QVariantList...which looks suspect. (Also: if you new, then who would do the delete?)
Have you tried returning it by value?