QByteArray to int always give 0 - qt

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.

Related

convert QByteArray to QString is empty

I use QTcpSocket::readAll() got a QByteArray. However when I used QString::fromUtf8() to convert it to QString, I got a empty QString.
QByteArray ba;
QDataStream in(&ba,QIODevice::ReadWrite);
in << socket->readAll();
QByteArray request = ba;
qDebug() <<"ba:" << ba; // right message
Then:
QString request = QString::fromUtf8(ba); // request is empty
QString request = QString(ba) //also empty
Maybe your bytearray has different text encoding (cyrillic - win1251 or DOS - cp866). For converting bytearray with specific encoding into string use QTextCodec
QByteArray ba("abcd");
QTextCodec *codec = QTextCodec::codecForName("CP1251");
QString str = codec->toUnicode(ba);
Your message is not coded in utf8, maybe GB18030.
In your main function, you must set your codec.
QTextCodec *gb = QTextCodec::codecForName("gb18030");
QTextCodec::setCodecForLocale(gb);
Then you can process the message(I am using Qt4).
QByteArray ba = s->readAll();
QString request = QString::fromLocal8Bit(ba.data(),ba.size());
...
QJsonDocument doc(jobject);
ByteArray arr = doc.toJson();
//Just cast
QString result = static_cast<QString>(doc.toJson());

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

store exact cv::Mat image in sqlite3 database

is there any way to store exact cv::Mat format data in sqlite3 using Qt.. as i will be using the same cv::Mat format in future..
i tried converting image to unsigned char* and them storing it.. but this didn't worked for me.. any other technique ??
You can serialize cv::Mat to QByteArray (see kde/libkface):
QByteArray mat2ByteArray(const cv::Mat &image)
{
QByteArray byteArray;
QDataStream stream( &byteArray, QIODevice::WriteOnly );
stream << image.type();
stream << image.rows;
stream << image.cols;
const size_t data_size = image.cols * image.rows * image.elemSize();
QByteArray data = QByteArray::fromRawData( (const char*)image.ptr(), data_size );
stream << data;
return byteArray;
}
Then store to DB.
To convert from QByteArray after reading from DB:
cv::Mat byteArray2Mat(const QByteArray & byteArray)
{
QDataStream stream(byteArray);
int matType, rows, cols;
QByteArray data;
stream >> matType;
stream >> rows;
stream >> cols;
stream >> data;
cv::Mat mat( rows, cols, matType, (void*)data.data() );
return mat.clone();
}
It works for me.

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;
}

Serializing QHash to QByteArray

I am trying to serialize a QHash object and store it in a QByteArray (to be sent using QUDPSocket or QTCPSocket).
My current attempt looks like this:
// main.cpp
#include <QtCore/QCoreApplication>
#include <QHash>
#include <QVariant>
#include <QDebug>
int main(int argc, char *argv[])
{
QHash<QString,QVariant> hash;
hash.insert("Key1",1);
hash.insert("Key2","thing2");
QByteArray ba;
QDataStream ds(&ba, QIODevice::WriteOnly);
ds << hash;
qDebug() << ds;
}
When this runs I get this out of qDebug():
QIODevice::read: WriteOnly device
QIODevice::read: WriteOnly device
QIODevice::read: WriteOnly device
QVariant(, )
The documentation says that this should write to the byte array, but obviously that isn't happening here. What am I doing wrong?
Qt 4.7.1 on OS-X
Thanks!
-J
The reason it is failing is because it is trying to read from a write-only stream. The sequence is:
qDebug() << ds;
--> QVariant::QVariant(QDataStream &s)
--> QDataStream& operator>>(QDataStream &s, QVariant &p)
--> void QVariant::load(QDataStream &s)
That last method (and some more downstream) try to read from the data stream to convert its contents into a QVariant for display in qDebug. In other words, your actual code is fine; the debugging check is causing the failure.
You could check the contents of the byte array with something like:
qDebug() << ba.length() << ba.toHex();
You can Implement you program like this code:
QHash<QString,QVariant> options;
options["string"] = "my string";
options["bool"] = true;
QByteArray ar;
//Serializing
QDataStream out(&ar,QIODevice::WriteOnly); // write the data
out << options;
//setting a new value
options["string"] = "new string";
//Deserializing
// read the data serialized from the file
QDataStream in(&ar,QIODevice::ReadOnly);
in >> options;
qDebug() << "value: " << options.value("string");
ref

Resources