尝试使用 Qt QNetworkAccessManager 获取网页时,它总是返回“”
Posted
技术标签:
【中文标题】尝试使用 Qt QNetworkAccessManager 获取网页时,它总是返回“”【英文标题】:When trying to get a webpage using Qt QNetworkAccessManager, It always returns "" 【发布时间】:2015-01-07 22:15:06 【问题描述】:我正在尝试使用 Qt 获取网页并将其打印在屏幕上。问题是它总是打印“”。它不会进入完成的插槽。我不知道connect()是否有问题。代码编译时没有错误。 尝试不使用事件循环。
代码如下:
net.h
#ifndef NET_H
#define NET_H
#include <QObject>
#include <QtNetwork>
#include <QString>
#include <QDebug>
class net : public QObject
Q_OBJECT
public:
explicit net(QObject *parent = 0);
void get_site(QString url);
QString data;
signals:
public slots:
void err(QNetworkReply *);
void done(QNetworkReply *);
private:
;
#endif // NET_H
net.cpp:
#include "net.h"
net::net(QObject *parent) :
QObject(parent)
void net::get_site(QString url)
QNetworkAccessManager man;
QNetworkRequest request;
request.setUrl (QUrl(url));
connect (&man , SIGNAL(finished(QNetworkReply*)) ,this, SLOT(done(QNetworkReply*)));
connect (&man , SIGNAL(finished(QNetworkReply*)) ,this, SLOT(err(QNetworkReply *)));
man.get (QNetworkRequest(QUrl(url)));
void net::done(QNetworkReply * reply)
data = QString(reply->readAll ());
void net::err(QNetworkReply * reply)
data = QString(reply->errorString ());
还有main.cpp:
#include <QCoreApplication>
#include "net.h"
int main(int argc, char *argv[])
QCoreApplication a(argc, argv);
net netobj;
netobj.get_site("http://***.com");
qDebug() << netobj.data;
return a.exec();
【问题讨论】:
"尝试不使用事件循环。"嗯,有你的问题。如果不让事件循环完成它的工作,这是不可能发生的。在你的插槽中设置断点,看看会发生什么。 但是有一些来源没有使用它。我猜他们使用应用程序退出槽。我不确定。我是 Qt 的新手。 【参考方案1】:您的代码中存在一些主要问题。首先,您应该在 .h 文件中将 QNetworkAccessManager
作为类成员:
class net : public QObject
...
private:
QNetworkAccessManager nam;
;
您也不应该将finished
信号连接到两个不同的插槽。你的get_site
函数应该是这样的:
void net::get_site(QString url)
QNetworkRequest request;
request.setUrl (QUrl(url));
connect (&man , SIGNAL(finished(QNetworkReply*)) ,this, SLOT(done(QNetworkReply*)));
man.get (QNetworkRequest(QUrl(url)));
您应该通过以下方式管理返回的回复:
void net::done(QNetworkReply * reply)
if (reply->error() == QNetworkReply::NoError)
data = QString(reply->readAll ());
else
data = QString(reply->errorString ());
【讨论】:
谢谢。但还是同样的问题。似乎我应该等待使用事件循环获得响应。我想不出任何其他方式。 我不知道为什么它在回复完成之前就跳转到插槽。或者为什么它在回复得到内容之前完成! 发出finished
时是否返回错误?即data = QString(reply->errorString ());
行是否被执行?
不,它没有到达 else 块。只执行 if (reply->error() == QNetworkReply::NoError) 块。所以没有错误。【参考方案2】:
您的 QNetworkAccessManager 实例在您的 get_site
函数结束时超出范围。根据 Qt 文档,一个 QNetworkAccessManager 对于整个 Qt 应用程序应该足够了。您的对象应该在该函数的范围之外持续存在,因为接收响应所需的时间可能比该函数结束所需的时间更长。使 QNetworkAccessManager 成为您的网络类的成员,而不是 get_site
本地的自动变量。
请注意,您还需要管理 QNetworkReply 对象的生命周期,而不是使用delete
,而是使用deleteLater()
,否则您可能会泄漏内存。
【讨论】:
谢谢。问题仍然存在。也许有办法等待得到回应?我不知道为什么它在回复完成之前跳转到插槽。或者为什么它在回复得到内容之前完成! 如果您捕获并查看 Qt 返回的错误代码和错误字符串,它应该会告诉您。我会编辑帖子以向您展示如何,但 Nejat 写了一个新的答案来展示如何。您可以发布您遇到的错误吗? 回答了 Nejat。没有错误。使用事件循环可以正常工作。所以我想问题只是它没有等待得到响应。但我不知道具体原因。以上是关于尝试使用 Qt QNetworkAccessManager 获取网页时,它总是返回“”的主要内容,如果未能解决你的问题,请参考以下文章