How do I know which QNetworkReply belongs to QNetworkRequest in asynchronous design?

I can easily get asynchronous design in C #

HttpResponseMessage response = await httpClient.GetAsync(InputAddress.Text); { ....// run when request finished. And response closely relation to request. } 

But how can I do this in QT? I find some codes below. But still some questions.

  • Why (sentReply == reply) can determine if it is identical or not? Perhaps I can send the same request twice, request A, indicate B. The corresponding answer is A ', B'. but the answers come after order B ', A'. Does the code work or not?
  • If I want to run the code after the request is completed (for example, C # code), how to do it? I think I can bind a UUID to each request or bind a callback function pointer to a request? What is the best way to do this?

     QNetworkAccessManager *manager=new QNetworkAccessManager(this); connect(manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(requestFinished(QNetworkReply*))); QNetworkRequest request(QUrl(serverUrl)); QNetworkReply *sentReply = manager->post(request, buffer.toUtf8()); void requestFinished(QNetworkReply *reply) { QByteArray msg = reply->readAll(); if (sentReply == reply) qDebug("this is it"); } 
+6
source share
4 answers

I would suggest the following:

Add custom property to QNetworkReply using dynamic properties. In the finished slot, you can access them and call the appropriate method.

Example:

 QNetworkReply *reply = networkAccessManager->get(QNetworkRequest(QUrl("http://url.com")); reply->setProperty("login", QVariant("logindata"); connect(reply, SIGNAL(finished()), this, SLOT(replyFinished())); 

replyOpen slot:

 QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender()); if (reply) { if (reply->error() == QNetworkReply::NoError) { QString myCustomData = reply->property("login").toString(); if(myCustomData =="logindata") //do something } reply->deleteLater(); } 
+3
source

You can get the QNetworkRequest pointer from QNetworkReply

 connect(&manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(finishedS(QNetworkReply*))); //save pointer to orginal request-A in some global(class) variable void this::finishedS(QNetworkReply* QNR) { QNetworkRequest *req = QNR->request(); if (req == requestA ) { //request-A stored in global(class) variable qDebug()<<"It reply for request-A" } else { qDebug()<<"It reply for request-B" } } 
+2
source

An elegant way to do this is to connect to the lambda:

 QNetworkAccessManager* manager = new QNetworkAccessManager(this); QNetworkRequest request(QUrl(serverUrl)); QNetworkReply* reply = manager->get(request); // Note: reply is kept alive by Qt -> capture pointer. request will go // out of scope -> capture by value (ie take a copy) connect(reply, &QNetworkReply::finished, [request, reply](){ ....// run when request finished. And response closely relation to request. qDebug() << "reply, request: " << reply << request.url(); }); 

Just pay attention to the review rules for captured (between [] ) variables.

+2
source

In my case, I created an array of QNetworkAccessManager and QNetworkReply, I had parallel lines of loading execution, and I needed to send everyone's progress to the corresponding progress indicator.

So, I send a response signal [i] to the slot (bar ()), and in the slot I used a QNetworkReply object that points to the sender

 void MyClass::foo() { QNetworkAccessManager *manager[uploadLimit]; QNetworkReply *reply[uploadLimit]; reply[i] = manager[i]->post(request, multiPart); //QNetworkRequest request, QHttpMultiPart multiPart connect(reply[i], SIGNAL(uploadProgress(qint64,qint64)), this,SLOT(bar(qint64,qint64))); } void MyClass::bar(qint64,qint64) { QNetworkReply *rep = (QNetworkReply*) sender(); } 

I deleted unnecessary lines, this is not working code, I think it makes sense.

0
source

Source: https://habr.com/ru/post/969885/


All Articles