当 QNetworkAccessManager 完成时,Qt 检索在请求期间创建的附加数据

Posted

技术标签:

【中文标题】当 QNetworkAccessManager 完成时,Qt 检索在请求期间创建的附加数据【英文标题】:Qt retrieve additional data created during request when QNetworkAccessManager finished 【发布时间】:2020-11-25 21:46:58 【问题描述】:

我想创建一个 HTTP 请求并在响应中检索一些在请求期间创建的变量。

但是,QNetworkAccessManager 响应是异步的,并且使用 SIGNAL/SLOT 功能,因此无法再访问变量。

这是一个例子:

void makeRequest()

    manager = new QNetworkAccessManager(this);

    connect(manager, SIGNAL(finished(QNetworkReply*)),
            this, SLOT(replyFinished(QNetworkReply*)));
         
    // here is the datas I want to get in the reply
    // objectdata and objectdata2 are created just before the http request
    MyClass objectdata("randomseed");
    MyClass2 objectdata("randomseed") ;
            
    QUrl websiteurl = objectdata.getUrl();

    manager->get(QNetworkRequest(websiteurl));



void replyFinished (QNetworkReply *reply)

    if(reply->error())
    
        qDebug() << "ERROR!";
        qDebug() << reply->errorString();
    
    else
     
        QByteArray dataHttp = reply->readAll();
        // How can I get here objectdata and objectdata2 ?
        // I would like to do something like that this->dataSuccess(objectdata,objectdata2,dataHttp);
    

    reply->deleteLater();

在同步系统中不存在这个问题。 有解决这个问题的方法吗?

【问题讨论】:

好吧,把附加数据存储在你类的成员变量中。 【参考方案1】:

一种方法是在 lambda 中捕获局部变量,而不是为插槽使用单独的函数。

void makeRequest()

    manager = new QNetworkAccessManager(this);

    // here is the datas I want to get in the reply
    // objectdata and objectdata2 are created just before the http request
    MyClass objectdata("randomseed");
    MyClass2 objectdata("randomseed") ;

    connect(manager, &QNetworkAccessManager::finished, [this, objectdata, objectdata2](QNetworkReply *reply)
    
        if(reply->error())
        
            qDebug() << "ERROR!";
            qDebug() << reply->errorString();
        
        else
         
            QByteArray dataHttp = reply->readAll();
            dataSuccess(objectdata,objectdata2,dataHttp);
        

        reply->deleteLater();
             
            
    QUrl websiteurl = objectdata.getUrl();

    manager->get(QNetworkRequest(websiteurl));

另一种方法是在QNetworkRequest 中添加额外参数作为属性。

    // Save off the data in the request
    QNetworkRequest req(websiteurl);
    req.setAttribute(QNetworkRequest::User, QVariant::fromValue<MyClass>(objectdata));
    req.setAttribute(QNetworkRequest::User + 1, QVariant::fromValue<MyClass2>(objectdata2));
    manager->get(req);

...
    // Retrieve the data from the reply
    auto data1 = reply->request().attribute(QNetworkRequest::User).value<MyClass>();
    auto data2 = reply->request().attribute(QNetworkRequest::User + 1).value<MyClass2>();

【讨论】:

以上是关于当 QNetworkAccessManager 完成时,Qt 检索在请求期间创建的附加数据的主要内容,如果未能解决你的问题,请参考以下文章

在 MacOSX 上,当指定无效的身份验证凭据时,QNetworkAccessManager 进入无限循环

使用 QNetworkAccessManager 在 QT 中的 HTTP POST 请求

QNetworkAccessManager 和 XML 回复

QNetworkAccessManager 失败

QNetworkAccessManager 在 arch 上给出 ssl 错误

QNetworkAccessManager 仅适用于应用程序主功能