QNetworkAccessManager with multiple "finished" slots...



  • Hello,

    I have an instance of the QNetworkAccessManager which, after building a QNetworkRequest with data to post, I connect to a "finished" slot.

    Now all works well with using one slot for replies but I'd like to now use different slots for different replies.

    The problem is that only one of my slots get called and not the slot I wanted for the reply.

    Below is some sample code to better illustrate the problem. In the code sample below all of the "replies" get routed to "ProcessReceivedUpdates()" even though when I connected the slots I used different functions.

    What can I do to utilize different slots? Or do I only use one "finished" slot?

    Here is the implementation:

    @
    void QTPrimaryApplicationWindow::CheckForUpdates() {

    QNetworkRequest req;

    req.setUrl(QUrl("http://localhost/app/checkupdate.php"));

    QByteArray postData;
    postData.append("command=UpdateSoftwareCheck&");
    postData.append("ApplicationVersion=");
    postData.append(ApplicationVersion);

    MainNetConnector->setCookieJar(new QNetworkCookieJar(MainNetConnector));

    connect(MainNetConnector, SIGNAL(finished(QNetworkReply *)), this, SLOT(ProcessReceivedUpdates(QNetworkReply *)));

    MainNetConnector->post(req, postData);

    }

    void QTPrimaryApplicationWindow::ProcessReceivedUpdates(QNetworkReply* reply) {

    QByteArray bytes = reply->readAll();
    QString str = QString::fromUtf8(bytes.data(), bytes.size());
    GLint statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();

    if (statusCode == 200) {

    std::string Results = str.toStdString();

    if (Results == "") {

    return;

    }

    rapidxml::xml_document<char> ResultsFromUpdateServer;
    char *cstr = &Results[0];

    ResultsFromUpdateServer.parse<0>(cstr);

    rapidxml::xml_node<>* RootNode = ResultsFromUpdateServer.first_node("update");

    std::string IsUpdateAvailable = "";

    if (RootNode->first_node("available")) {

    IsUpdateAvailable = RootNode->first_node("available")->value();

    }

    if (IsUpdateAvailable == "true") {

    ApplicationUpdate* NewUpdate = new ApplicationUpdate();

    NewUpdate->SetVersion(RootNode->first_node("version")->value());
    NewUpdate->SetURL(RootNode->first_node("url")->value());
    NewUpdate->SetDescription(RootNode->first_node("description")->value());

    std::string IsCritical = RootNode->first_node("critical")->value();

    if (IsCritical == "1" || IsCritical == "true") {

    NewUpdate->SetCritical(true);
    

    }
    else {

    NewUpdate->SetCritical(false);
    

    }

    NewUpdate->SetReleaseDate(RootNode->first_node("releasedate")->value());
    NewUpdate->SetModificationDate(RootNode->first_node("modificationdate")->value());

    QTUpdateDialog* Updater = new QTUpdateDialog(this);
    Updater->resize(526, 325);
    Updater->SetUpdateToDisplay(NewUpdate);
    Updater->setModal(true);
    Updater->exec();

    }
    else {

    statusBar()->showMessage(tr("Your application is up to date."));

    }

    }

    }

    void QTPrimaryApplicationWindow::LogFileOpen() {

    QNetworkRequest req;

    req.setUrl(QUrl("http://localhost/app/processfile.php"));

    QByteArray postData;
    postData.append("command=InsertFileOpen&");
    postData.append("ApplicationVersion=");
    postData.append(ApplicationVersion);

    MainNetConnector->setCookieJar(new QNetworkCookieJar(MainNetConnector));

    connect(MainNetConnector, SIGNAL(finished(QNetworkReply *)), this, SLOT(ProcessFileOpen(QNetworkReply *)));

    MainNetConnector->post(req, postData);

    }

    void QTPrimaryApplicationWindow::LogFileClose() {

    if (!CurrentlyOpenFile) {

    return;

    }

    QNetworkRequest req;

    req.setUrl(QUrl("http://localhost/app/processfile.php"));

    QByteArray postData;
    postData.append("command=InsertFileClose&");
    postData.append("ApplicationVersion=");
    postData.append(ApplicationVersion);

    MainNetConnector->setCookieJar(new QNetworkCookieJar(MainNetConnector));

    connect(MainNetConnector, SIGNAL(finished(QNetworkReply *)), this, SLOT(ProcessFileClose(QNetworkReply *)));

    MainNetConnector->post(req, postData);

    }

    void QTPrimaryApplicationWindow::ProcessFileOpen(QNetworkReply* reply) {

    QByteArray bytes = reply->readAll();
    QString str = QString::fromUtf8(bytes.data(), bytes.size());
    GLint statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();

    if (statusCode == 200) {

    std::string Results = str.toStdString();

    if (Results == "") {

    return;

    }

    rapidxml::xml_document<char> ResultsFromUpdateServer;
    char *cstr = &Results[0];

    ResultsFromUpdateServer.parse<0>(cstr);

    rapidxml::xml_node<>* RootNode = ResultsFromUpdateServer.first_node("logfileprocess");

    std::string SuccessLog = "";

    if (RootNode->first_node("success")) {

    SuccessLog = RootNode->first_node("success")->value();

    }

    if (SuccessLog == "true") {

    CurrentlyOpenFile->SetFileProcessID(RootNode->first_node("fileprocessid")->value());

    }
    else {

    /*

    Do something when not successful..

    */

    }

    }

    }

    void QTPrimaryApplicationWindow::ProcessFileClose(QNetworkReply* reply) {

    QByteArray bytes = reply->readAll();
    QString str = QString::fromUtf8(bytes.data(), bytes.size());
    GLint statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();

    if (statusCode == 200) {

    std::string Results = str.toStdString();

    if (Results == "") {

    return;

    }

    rapidxml::xml_document<char> ResultsFromUpdateServer;
    char *cstr = &Results[0];

    ResultsFromUpdateServer.parse<0>(cstr);

    rapidxml::xml_node<>* RootNode = ResultsFromUpdateServer.first_node("logfileprocess");

    std::string SuccessLog = "";

    if (RootNode->first_node("success")) {

    SuccessLog = RootNode->first_node("success")->value();

    }

    if (SuccessLog == "true") {

    /*

    Do something when successful.

    */

    }
    else {

    }

    }

    }
    @



  • Why don't you just connect to the relevant QNetworkReply::finished() signal ?



  • [quote author="sandy.martel" date="1418267901"]Why don't you just connect to the relevant QNetworkReply::finished() signal ?
    [/quote]

    I apologize if I don't follow; I am new at Qt. I am not sure what you mean in this case.

    Are you saying I should have one function and then use the QNetworkReply object supplied in a "finished()" function slot?



  • something like:

    @
    auto reply = MainNetConnector->post(req, postData);

    connect(reply, &QNetworkReply::finished, this, &QTPrimaryApplicationWindow::ProcessFileClose );

    void QTPrimaryApplicationWindow::ProcessFileClose()
    {
    auto reply = object_cast< QNetworkReply *>( sender() );
    QByteArray bytes = reply->readAll();
    ...

    reply->deleteLater(); // avoid a memory leak, like in your example.
    }
    @



  • Thank you, I will try this out!


Log in to reply
 

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