尝试使用 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-&gt;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 获取网页时,它总是返回“”的主要内容,如果未能解决你的问题,请参考以下文章

一Qt初尝试,做一个QT计算器《QT 入门到实战》

一Qt初尝试,做一个QT计算器《QT 入门到实战》

尝试使用共享库部署 Qt 应用程序时出错

Qt连接尝试使用父类

Qt异常处理 - 尝试catch

尝试使用 Qt QNetworkAccessManager 获取网页时,它总是返回“”