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

Qt Asynchronous Method To Synchronous Method



  • Hi, I am new to Qt and I am having trouble converting this following Asynchronous function to Synchronous function.

    There is an application which has importing a file functionality which then posts the file path to the server it will check if the file is in the supported format or not and it returns the path of the file as the response.

    Ex:
    file1.cpp

    void ImportScanFile( QString filePath)
    {
     classB *objB = new classB();
     classB->checkFileIsSupported(filePath);
    }
    

    file2.cpp

    void checkFileIsSupported(QString filePath)
    {
    QUrl url(QUrl::fromLocalFile(serveraddress + '/' + filepath);
    url.setScheme("http");
    url.setHost("127.0.01");
    url.setPort("8006");
    
    QNetworkRequest request(url);
    QNetworkAccessManagerObj->post(request, QByterArray());
    }
    
    //Following slot is invoked when post request are made
    void onRequestFinished(QNetworkReply* reply)
    {
     QNetworkRequest request = reply->request();
     QString requestPath = request.url().toString();
    
     if(reply->error() !=  QNetworkReply::NoError)
     {
       if( requestPath.contains(filePath))
        {
          show qMessage with txt "Failed to import".
        }
      }
     else if( reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 200)
     {
       QString filePath = reply->readAll().data()
       if( filePath.empty())
       {
            show qMessage with txt "Failed to import".
       }
       else
       {
       if( importScan(filePath)) //This function will print scan data on the model
       {
           show qMessage with txt "Successfully Imported".
       }
       else
      {
         show qMessage with txt "Failed to import".
       }
      }
     }
    }
    

    Above as you can see that after the checkFileIsSupported() post call the control will go back to ImportScanFile() and it exit the function and then onRequestFinished() slot is called and the msg box will appear after the execution of ImportScanFile() this is Asynchronous as the msg are coming after the original function checkFilesInSupported() finished execution . How can I send back the response from the server to the place from where the checkFileIsSupported() is getting called so i can handle everything there itself and make everything Synchronous.


  • Moderators

    @Abhi_Varma said in Qt Asynchronous Method To Synchronous Method:

    How can I send back the response from the server to the place from where the checkFileIsSupported() is getting called so i can handle everything there itself and make everything Synchronous.

    First, it is important to know that if you make your code synchronous, your GUI will freeze until the import is finished. Are you sure you want this?

    Second, there is no need to write synchronous code. If you want to put all the slot's code inside checkFileIsSupported(), you can connect the QNetworkReply::finished() signal to a lambda function (don't connect QNetworkAccessManager::finished()):

    void checkFileIsSupported(QString filePath)
    {
        QUrl url(QUrl::fromLocalFile(serveraddress + '/' + filepath);
        url.setScheme("http");
        url.setHost("127.0.01");
        url.setPort("8006");
    
        QNetworkRequest request(url);
        QNetworkReply* reply = QNetworkAccessManagerObj->post(request, QByteArray());
    
        connect(reply, &QNetworkReply::finished, [=]
        {
            // QNetworkRequest request = reply->request(); // NOTE: This line is unnecessary; you can capture the QNetworkRequest in the lambda directly
            QString requestPath = request.url().toString();
    
            if(reply->error() !=  QNetworkReply::NoError)
            {
                ...
            }
            else if( reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 200)
            {
                ...
            }
    
            // IMPORTANT: Remember to delete your QNetworkReply, or else you have a memory leak
            reply->deleteLater();
        });
    }
    

    There are many tutorials online that show you how to use lambdas.


Log in to reply