QNetworkReply issue
-
Hello, I am trying to figure out why I am receiving different numbers each time I print out my reply statement and I want to know what is it printing out?
params.addQueryItem("username",username); params.addQueryItem("password",password); QByteArray data; data.append(params.toString().mid(1)); QNetworkRequest request(QUrl("weburl/login.php")); request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/x-www-form-urlencoded")); QNetworkAccessManager *nam = new QNetworkAccessManager; QNetworkReply *reply = nam->get(request); qDebug() << reply;
It prints out something like this:
QNetworkReplyImpl(0x412db688d0)
Could someone explain to me why this happens? (The php script works fine for my game and will return something likeelse echo json_encode(array('status'=>'Login information is incorrect. Check your username and password.')); //wrong password
) -
Hi,
@Ericode said:
Hello, I am trying to figure out why I am receiving different numbers each time I print out my reply statement and I want to know what is it printing out?
// ... QNetworkReply *reply = nam->get(request); qDebug() << reply;
It prints out something like this:
QNetworkReplyImpl(0x412db688d0)
In your code,
reply
is a pointer to a QNetworkReply object. You asked your program to print the value of this pointer, which is the object's memory address. Each time you run your code, the object is created at a different memory address, that's why you see a different value each time.To get the contents of the network reply, you need to listen for the
QNetworkReply::finished()
signal. The QNetworkReply object emits this signal when it finishes downloading the data. Connect this signal to a slot that callsQNetworkReply::readAll()
-- this gives you the downloaded data.Remember to delete the QNetworkReply after that, or else you will get a memory leak.
-
QUrlQuery params; params.addQueryItem("username",username); params.addQueryItem("password",password); QByteArray data; data.append(params.toString().mid(1)); QNetworkRequest request(QUrl("weburl/mmologin.php")); request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/x-www-form-urlencoded")); QNetworkAccessManager *nam = new QNetworkAccessManager; QNetworkReply *reply = nam->get(request); connect(reply, SIGNAL(finished()), SLOT(replyFinished(reply)));
This is the updated code along with a new method
void MainWindow::replyFinished(QNetworkReply *reply) { qDebug() << "Request Finished"; }
Is this what you ment?
-
@Ericode said:
connect(reply, SIGNAL(finished()), SLOT(replyFinished(reply)));
This is the updated code along with a new method
void MainWindow::replyFinished(QNetworkReply *reply) { qDebug() << "Request Finished"; }
Is this what you ment?
Almost.
Have you used signals and slots before? Your code has the right idea, but it won't work currently because you can't pass a parameter to the slot like that. You have a few options:
Option 1: Store the reply pointer and retrieve it later
void MainWindow::login() { // ... // "reply" is a member variable of MainWindow this->reply = nam->get(request); connect(this->reply, SIGNAL(finished()), this, SLOT(replyFinished())); // <-- NOTE: You should specify the pointer to the slot owner ("this") } void MainWindow::replyFinished() { qDebug() << "Request Finished:" << this->reply->readAll(); // Prevent memory leak this->reply->deleteLater(); }
Option 2: Use a C++11 lambda expression to capture the reply pointer
void MainWindow::login() { // ... // "reply" is a local variable QNetworkReply *reply = nam->get(request); connect(reply, &QNetworkReply::finished, [=] { qDebug() << "Request Finished:" << reply->readAll(); // Prevent memory leak reply->deleteLater(); }); }
-
@JKSH
Thank you so much for your help. I am glad you showed me both ways to implement this. My only concern now is the QJsonArray. My php is decoding the json array but in qt I am having some issues making one.QJsonArray params; params[0] = username; params[1] = password; QNetworkRequest request(QUrl("weburl/mmologin.php")); request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/x-www-form-urlencoded")); QNetworkAccessManager *nam = new QNetworkAccessManager; nam->post(request, params.toString(QUrl::FullyEncoded).toUtf8()); // This line is wrong as QJsonArray does not have a tostring method but I am not sure how else to encode it QNetworkReply *reply = nam->get(request);
How would I take params and send it to my web url encoded as a json array?
-
You're welcome :)
@Ericode said:
nam->post(request, params.toString(QUrl::FullyEncoded).toUtf8()); // This line is wrong as QJsonArray does not have a tostring method but I am not sure how else to encode it
...
How would I take params and send it to my web url encoded as a json array?Embed your QJsonArray in a QJsonDocument first, then call QJsonDocument::toJson().
-
@JKSH
Ok, so I created a QJsonDocument but my issue is calling the QJsonDocument::toJson. How does it know which object I want to covert to json? Also, nam->post(request); only takes one parameter so how would I be able to tell it to send the doc or params along with it?QJsonArray params; params[0] = username; params[1] = password; QJsonDocument doc; doc.setArray(params); QJsonDocument::toJson(); nam->post(request);
-
QStringList propertyNames; QStringList propertyKeys; QString strReply = (QString)reply->readAll(); QJsonDocument jsonResponse = QJsonDocument::fromJson(strReply.toUtf8()); QJsonObject jsonObject = jsonResponse.object(); QJsonArray jsonArray = jsonObject["properties"].toArray(); foreach (const QJsonValue & value, jsonArray) { QJsonObject obj = value.toObject(); propertyNames.append(obj["PropertyName"].toString()); propertyKeys.append(obj["key"].toString()); }
I saw something like this online which is similar to what I want but my question is how can I put multiple values in the QJsonArray. Here the values come from
QString strReply = (QString)reply->readAll()
but I have 2 values I want to go into the json array "username" from the variable username and "password" from the variable password. -
@Ericode said:
Ok, so I created a QJsonDocument but my issue is calling the QJsonDocument::toJson. How does it know which object I want to covert to json? Also, nam->post(request); only takes one parameter so how would I be able to tell it to send the doc or params along with it?
toJson()
turns everything in your QJsonDocument into a JSON string, which you can post to your server.If you don't want something to be sent, don't add it into your document.
I suggest you inspect the QJsonDocument and the string produced by
toJson()
usingqDebug()
-- this should give you useful insight into how the whole thing works.I also suggest reading this example: http://doc.qt.io/qt-5/qtcore-json-savegame-example.html
Here the values come from QString strReply = (QString)reply->readAll() but I have 2 values I want to go into the json array "username" from the variable username and "password" from the variable password.
Sorry, I don't quite get what you're describing. Could you please post an example of what your final array should look like?
-
{ "password": "d", "username": "d" }
This is what my json array looks like when it is sent to my php script. Is there way to make it look something like (with the title "Array")?
{ "Array": [ true, 999, "string" ], "Key": "Value", "null": null }
p.s. Does the debug statement below also read echo statements from the php script such as
echo json_encode(array('status'=>'Login information is incorrect. Check your username and password.'));
connect(reply, &QNetworkReply::finished, [=] { qDebug() << "Request Finished:" << reply->readAll(); reply->deleteLater(); });