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 like else echo json_encode(array('status'=>'Login information is incorrect. Check your username and password.')); //wrong password)


  • Moderators

    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 calls QNetworkReply::readAll() -- this gives you the downloaded data.

    Remember to delete the QNetworkReply after that, or else you will get a memory leak.



  • @JKSH

        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?


  • Moderators

    @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?


  • Moderators

    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.


  • Moderators

    @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() using qDebug() -- 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?



  • @JKSH

    {
        "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();
        });
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.