我怎么知道哪个QNetworkReply属于异步设计中的QNetworkRequest?

时间:2014-05-27 05:31:19

标签: qt qt5

我可以在C#中轻松获得异步设计

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

但我怎样才能在QT中做到这一点?我在下面找到一些代码。但还是有些问题。

  1. 为什么(sentReply == reply)可以确定它是否相同?也许我可以发送两次相同的请求,请求A,请求B.相应的响应是A',B'。但响应按照B',A'顺序到达。代码是否有效?
  2. 如果我想在请求完成时运行一些代码(如上面的c#代码),我该怎么做?我想我可以将UUID绑定到每个请求或绑定一个回调函数指针来请求?最好的方法是什么?

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

4 个答案:

答案 0 :(得分:4)

我建议如下:

使用动态属性将自定义属性添加到QNetworkReply。 在完成的Slot中,您可以访问它们并调用相应的方法。

示例:

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

connect(reply, SIGNAL(finished()), this, SLOT(replyFinished()));

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

答案 1 :(得分:2)

您可以从QNetworkReply

获取QNetworkRequest指针
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's reply for request-A"
} else {
qDebug()<<"It's reply for request-B"
}
}

答案 2 :(得分:2)

一种优雅的方式是连接到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 (i.e. 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(); });

请注意捕获的([])变量之间的范围规则。

答案 3 :(得分:0)

在我的情况下,我创建了一个QNetworkAccessManager和QNetworkReply数组,我有并行上传进度条,我需要将每个进度发送到相应的进度条。

所以,我将回复[i]的信号发送到插槽(bar()),在插槽中我使用指向发送者的QNetworkReply对象

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

我删除了不必要的行,这不是一个正常工作的代码,我认为这是重点。