Transmit QMap by QMimeData - qt

Is any ideas how i can transmit QMap<QString, QString> in Drag and Drop mode by using QMimeData?
Now i convert QMap into QString like this:
"key1:value1;key2:value2;...keyN:valueN" and assigned it to QMimeData::setText().
Then on dropEvent() i rebuild QMap from QString. Is this right way?
Convert QString to QMap
...
QStringList splittedParams = params.split(";");
QMap<QString, QString> *map = new QMap<QString, QString>();
foreach(QString param, splittedParams)
{
if(param.isEmpty()) continue;
QStringList str = param.split(":");
map->insert(str[0], str[1]);
}
...

That's going to fall apart if your strings contain the separators. For a more robust approach use something like
QByteArray ba;
QDataStream ds(&ba, QIODevice::WriteOnly);
map >> ds;
mimeData->setData(QStringLiteral("your/mime/type"), ba);

Related

Converting QMap<QString, QString> to Json string results empty

I have a function defined and used as this:
// usage:
QMap<QString, QString> map = ...;
foo(map);
// defination:
QString stringMapToJson(const QMap<QString, QString>& arg) {
QVariant v = QVariant::fromValue(arg);
JsonDocument doc = QJsonDocument::fromVariant(v);
...
}
Then I realized v is empty.
Is there a method to convert QMap<String, QString> to QMap<String, QVariant>, so above v could be valid?
Why above v is empty? I read people were saying QVariant and qMetaData, I don't understand given the following valid, why QString have a qMetaData problem:
QString s = "";
QVariant v = s;
(A Java programmer starts her pleasant C++ journey.)
Thanks.
There are 2 ways to do this. The first is to convert your map to a QMap<QString, QVariant> like you mentioned:
QByteArray stringMapToJson1(const QMap<QString, QString>& arg)
{
QVariantMap vmap;
for(auto it = arg.cbegin(); it != arg.cend(); ++it)
{
vmap.insert(it.key(), it.value());
}
const QVariant v = QVariant::fromValue(vmap);
const QJsonDocument doc = QJsonDocument::fromVariant(v);
return doc.toJson();
}
Alternatively, you can build the json object directly from the map. In this case it's the same amount of code:
QByteArray stringMapToJson2(const QMap<QString, QString>& arg)
{
QJsonObject jObj;
for(auto it = arg.cbegin(); it != arg.cend(); ++it)
{
jObj.insert(it.key(), it.value());
}
QJsonDocument doc;
doc.setObject(jObj);
return doc.toJson();
}
This seems like a stylistic choice and I am unsure which would be faster. Both produce the same output.
One thing to note: The conversion from QString to QVariant is predefined in Qt, so the first method works fine. For objects of your own classes you would have to register that type and provide a suitable conversion which can be a bit tough to get right. In the second method you could do this conversion inline in the loop.

QByteArray to int always give 0

I try to send data throw qtcpsocket and use QByteArray. I send previosly size of data and try convert to int like this QByteArray to Int conversion.
But always get 0. Code convertion example:
QString ss = "bca";
int aaa;
QByteArray b;
QDataStream stream(&b, QIODevice::ReadWrite);
stream << ss.toUtf8().size();
stream >> aaa;
In this example aaa is always 0, but ss.toUtf8().size() isnt. What im doing wrong?
QString ss = "bca";
int aaa;
QByteArray b;
QDataStream stream(&b, QIODevice::ReadWrite);
stream << ss.toUtf8().size();
stream.device().seek(0); // add this code
stream >> aaa;
The inner pointer of QByteArray is at the end, so nothing can be read.

How can I get convert wstringstream to char*?

how convert wstringstream to char* ?? (Language c++)
I need this conversion to use the function writeRawData of the qdatastream.h library.
Thank you very much!!
You have to use wstringstream::str() to retrieve the content of the stream.
And then depending on your need you can either convert it to a QString so that the QDataStream can handle the string for you or just write the bytes of the wstring:
void f(wstringstream &stream, QDataStream &qstream)
{
wstring content = stream.str();
QString str = QString::fromStdWString(content);
qstream << str;
}
void g(wstringstream &stream, QDataStream &qstream)
{
wstring content = stream.str();
qstream.writeRawData(static_cast<const char *>(content.c_str()), content.length() * sizeof(wchar_t));
}
wstringstream is a basic_stringstream, you could extract line, char, text from it
look at that http://www.cplusplus.com/reference/sstream/wstringstream/
and you could retreive one example from that http://www.cplusplus.com/reference/sstream/basic_stringstream/str/

QPixmap.loadFromData() does not load image from QByteArray

I'm creating a socket-based program to send a screenshot from one user to another user. I need to convert a screenshot to a byte array before sending. After I convert my screenshot to a QByteArray I insert 4 bytes to the beginning of the array to mark that it is a picture (it is the number 20 to tell me it is a picture and not text or something else).
After I send the byte array via a socket to other user, when it is received I read the first 4 bytes to know what it is. Since it was a picture I then convert it from a QByteArray to QPixmap to show it on a label. I use secondPixmap.loadFromData(byteArray,"JPEG") to load it but it not load any picture.
This is a sample of my code:
void MainWindow::shootScreen()
{
originalPixmap = QPixmap(); // clear image for low memory situations
// on embedded devices.
originalPixmap = QGuiApplication::primaryScreen()->grabWindow(0);
scaledPixmap = originalPixmap.scaled(500, 500);
QByteArray bArray;
QBuffer buffer(&bArray);
buffer.open(QIODevice::WriteOnly);
originalPixmap.save(&buffer,"JPEG",5);
qDebug() << bArray.size() << "diz0";
byteArray= QByteArray();
QDataStream ds(&byteArray,QIODevice::ReadWrite);
int32_t c = 20;
ds << c;
ds<<bArray;
}
void MainWindow::updateScreenshotLabel()
{
this->ui->label->setPixmap(secondPixmap.scaled(this->ui->label->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
}
void MainWindow::on_pushButton_clicked()
{
shootScreen();
}
void MainWindow::on_pushButton_2_clicked()
{
secondPixmap = QPixmap();
QDataStream ds(&byteArray,QIODevice::ReadOnly);
qint32 code;
ds>>code;
secondPixmap.loadFromData(byteArray,"JPEG");
updateScreenshotLabel();
}
Your MainWindow::on_pushButton_2_clicked implementation looks odd. You have...
QDataStream ds(&byteArray,QIODevice::ReadOnly);
which creates a read-only QDataStream that will read it's input data from byteArray. But later you have...
secondPixmap.loadFromData(byteArray,"JPEG");
which attempts to read the QPixmap directly from the same QByteArray -- bypassing the QDataStream completely.
You can also make use of the QPixmap static members that read from/write to a QDataStream. So I think you're looking for something like...
QDataStream ds(&byteArray,QIODevice::ReadOnly);
qint32 code;
ds >> code;
if (code == 20)
ds >> secondPixmap;
And likewise for your MainWindow::shootScreen implementation. You could reduce your code a fair bit by making use of QDataStream & operator<<(QDataStream &stream, const QPixmap &pixmap).

Qt QList<QString> serialization for database

I have a QList list. I want to insert it on the database. I didn't find any serializer method after some googling. If there any method / idea to serialize the list data for database?
How about using QStringList instead of QList<QString> -
QStringList numberList_; // instead of QList<QString>, use this
QString myString1 = "Hello";
QString myString2 = "World";
numberList_ << myString1;
numberList_ << myString2;
QByteArray byteArray;
QBuffer buffer(&byteArray);
QDataStream out(&buffer);
out << numberList_;
Probably QList<QString> should also work in place of QStringList. If it doesn't, well, you can convert it pretty easily to QStringList.
QDataStream, QBuffer,
QByteArray and QStringList reference.
Here is another option that is a bit more succinct:
QString serialize(QStringList stringList)
{
QByteArray byteArray;
QDataStream out(&byteArray, QIODevice::WriteOnly);
out << stringList;
return QString(byteArray.toBase64());
}
QStringList deserialize(QString serializedStringList)
{
QStringList result;
QByteArray byteArray = QByteArray::fromBase64(serializedStringList.toUtf8());
QDataStream in(&byteArray, QIODevice::ReadOnly);
in >> result;
return result;
}

Resources