QNetworkReply 等待完成

Posted

技术标签:

【中文标题】QNetworkReply 等待完成【英文标题】:QNetworkReply wait for finished 【发布时间】:2011-03-30 12:11:31 【问题描述】:

我正在使用 Qt 4.6.3 和以下不工作的代码

QStringList userInfo;
QNetworkRequest netRequest(QUrl("http://api.***.com/1.1/users/587532"));
QNetworkReply *netReply = netman->get(netRequest);

// from here onwards not working
netReply->waitForReadyRead(-1);
if (netReply->isFinished()==true)
userInfo << do sth to reply;
return userInfo;

由于此函数返回一个空的 QStringList,应用程序崩溃。如何等到请求完成后再处理回复在一个函数中

【问题讨论】:

老问题,但仍然非常相关。 Qt 老实说应该为QNetworkReply 提供一个waitForFinished()' 函数。 【参考方案1】:

你可以使用事件循环:

QEventLoop loop;
connect(netReply, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec();
// here you have done.

您还应该考虑添加一些比网络超时更短的时间(20 秒?)。即使发生错误,我也不确定是否调用了完成。因此,您也有可能连接到错误信号。

【讨论】:

另外另一个答案还包括提到QEventLoop,这个答案立刻就正确了。 还没有遇到过调用完成槽的情况。我知道文档说它通常会被调用,但对我来说它总是被调用 这只是意味着你应该考虑连接一些额外的信号。它是否“总是被我召唤”并不重要。可能会出现(如文档所说)您不会收到finished() 信号的情况,因此您的事件循环将被卡住【参考方案2】:

首先我建议您阅读 Qt 文档参考中的相关文档,您可以在此处找到:http://doc.qt.nokia.com/latest/classes.html

查看您的代码示例,您似乎已经拥有QNetworkRequestQNetworkReply 以及QNetworkAccessManager。您需要将插槽连接到finished(QNetworkReply *) 信号。每当挂起的网络回复完成时,就会发出此信号。

QNetworkAccessManager *manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished(QNetworkReply*)),
        this, SLOT(replyFinished(QNetworkReply*)));

manager->get(QNetworkRequest(QUrl("http://api.***.com")));

现在,在您的插槽中,您可以读取响应您的请求而发送的数据。比如:

void MyClass::MySlot(QNetworkReply *data) 
    QFile file("dataFromRequest");
    if (!file.open(QIODevice::WriteOnly))
        return;
    file.write(data->readAll());
    file.close();

编辑:

要同步等待信号,请使用 QEventLoop。你这里有一个例子

http://wiki.forum.nokia.com/index.php/How_to_wait_synchronously_for_a_Signal_in_Qt

【讨论】:

我也知道这一点,但我怎么能在同一个函数中返回接收到的数据(我不希望\有一个额外的插槽函数)【参考方案3】:

这里的这些回复都是使用旧语法,不适用于最新的QT。

等待网络请求完成:

QEventLoop loop;
connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
loop.exec();

【讨论】:

以上是关于QNetworkReply 等待完成的主要内容,如果未能解决你的问题,请参考以下文章

QEventLoop等待另外一个事件的停止,非常实用 good

QNetworkReply 在发出完成信号时抛出 SIGSEGV

Visual Basic 服务器和 Qt 客户端(QNetworkReply 完成较新的发布)

QNetworkReply 未被删除

QNetworkReply::error 信号何时会跟随finished() 信号?

Qt QNetworkAccessManager 和多个 QNetworkReply