Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Wait till POST request finished



  • My program is getting data from mysql table via json format through php script, that generating json.

    My function sends to server post request (with some params) and getting response. With that all okay. Works fine. But, when I want to get specified cell (data from json array), it takes empty string (program works fast and taking data from a string before it sets up)

    Here's the code with post request:

    void dbase::requestor(QString option)
    {
        curr_js = ""; //nulling string
        QString urla = host+"transfer.php";
        // /////////
        QNetworkAccessManager * manager = new QNetworkAccessManager(this);
        QUrl url(urla);
        QNetworkRequest request(url);
        request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
        QUrlQuery params;
        params.addQueryItem("api", key);
        params.addQueryItem("option", option);
        //QEventLoop loop;
        connect(manager, SIGNAL(finished(QNetworkReply *)),this, SLOT(replyFinished(QNetworkReply *)));
        //loop.exec(); tryed eventloop, but bcuz of this my replyFinished is not accessible. error code under this one
        manager->post(request, params.query().toUtf8());
    
    }
    

    If using eventloop

    QObject::connect: No such slot QEventLoop::replyFinished(QNetworkReply *)
    

    replyFinished function (setting up variable)

    void dbase::replyFinished(QNetworkReply *reply)
    {
        curr_js = reply->readAll();
    }
    

    Usage (where is problem)

    QString req = "SOME REQUEST";
        database.requestor(req);
        if (database.db_cell (0,0) == "")
        {
            qDebug()<<database.db_cell (0,0) << " - EMPTY - "<<database.curr_js;
        }
    

    So in this case I'm getting

    ""  - EMPTY -  ""
    

    But if I getting data from string (created button for test), it's there:

    {"0":["1", "Admin","hashpwd"],"1":["2", "Albert","hashpwd"]}
    

    db_cell function

    QString dbase::db_cell (int indexrow, int indexcols)
    {
        QJsonDocument sd = QJsonDocument::fromJson(curr_js.toUtf8());
        QJsonObject setobj = sd.object();
        QJsonValue qqq = setobj.value(QString(QString::number(indexrow))).toArray()[indexcols];
        return qqq.toString();
    }
    

    As I see, problem is that program need to wait before getting a data from json-string.



  • @Andre-Muller You can't use QEventLoop to access class slot. Or you can, but not in the way you thought.
    The ususal way to use QEventLoop is:

    QEventLoop loop;
    QNetworkReply* rely = manager->post(request, params.query().toUtf8());
    connect(rely , SIGNAL(finished()), &loop, SLOT(quit()));
    loop.exec();
    //read from reply, or you can call the class slot / any class function here
    reply->deleteLater();
    

    or in the new syntax:

    connect(rely , &QNetworkReply::finished, &loop, &QEventLoop::quit);
    

    And are you creating a new QNetworkAccessManager for every request?
    Wow, that is not we usually do, either.


  • Qt Champions 2019

    @Andre-Muller said in Wait till POST request finished:

    database.requestor(req);

    Since the whole is async you have to wait until the reply is finished (what you're already doing and already executing dbase::replyFinished(). From there you can send a signal to process your data further.



  • @Christian-Ehrlicher send signal? but how prevent code running while it finishes? can You provide some examples? just didn't get how to make it working.

    and, btw, I thought, good option will be eventloop. I mean, it will pause running while data is getting.

    Here's sample:

    QEventLoop loop;
       manager->post(request, params.query().toUtf8());
       connect(manager, SIGNAL(finished(QNetworkReply *)),&loop, SLOT(replyFinished(QNetworkReply *)));
       loop.exec();
    

    But if I replace 'this' param from connect by '&loop" I cant access anymore to 'replyFinished'.

    QObject::connect: No such slot QEventLoop::replyFinished(QNetworkReply *)
    

    How can I use Eventloop and access to class slot? Or, if u know how to solve problem in other way, I will be grateful.



  • @Andre-Muller You can't use QEventLoop to access class slot. Or you can, but not in the way you thought.
    The ususal way to use QEventLoop is:

    QEventLoop loop;
    QNetworkReply* rely = manager->post(request, params.query().toUtf8());
    connect(rely , SIGNAL(finished()), &loop, SLOT(quit()));
    loop.exec();
    //read from reply, or you can call the class slot / any class function here
    reply->deleteLater();
    

    or in the new syntax:

    connect(rely , &QNetworkReply::finished, &loop, &QEventLoop::quit);
    

    And are you creating a new QNetworkAccessManager for every request?
    Wow, that is not we usually do, either.



  • @Bonnie so how to do right then? how to solve this problem? just no idea, fighting 2 days with it.



  • @Andre-Muller I've already written how to wait till finished for you, what do you not understand?
    The usual way for using QNetworkAccessManager is only create it once and keep reusing the instance (while in the same thread).


  • Qt Champions 2019

    @Andre-Muller said in Wait till POST request finished:

    but how prevent code running while it finishes?

    Why do you want this? It will block your ui for no good reason.



  • @Bonnie oh, sorry, didn't tested ur code, thought it's just syntax explanation.
    All working well now. Thx a lot.


Log in to reply