7

我正在使用 qt5.3,在发布之前我搜索了很多。

我想从中读取数据QNetworkReply。我有一个QWebView并且我还需要读取 http 响应来QWebView显示网页。我需要的只是记录网页内容或对 http 帖子的任何响应。

问题是QNetworkReply只能读取一次的东西。

  1. 如果我readAll()在选择readyRead()信号时打电话,我会得到完整的数据。但它会被清除所以QWebView什么都不显示(它不会得到任何回复数据)。

  2. 或者如果我选择finished()信号,因为数据已经被QWebView(或QNetworkAccessManager)读取,如果我readAll()在这里调用,我什么也得不到。是否有某个地方QNetworkReply、经理或任何班级存储我仍然可以读取的数据?

在 #1 中,如果我调用peek(). 此功能不会清除响应数据。但是如果响应体很大,它就行不通了。这QNetworkReply是一个顺序的东西,我既不能知道它的数据,也不能比缓冲的读得更远。

我不知道如何处理这个......

我只想监视和记录在我的QWebView...上提出的任何请求的请求和响应正文。

编辑:请注意,我要从响应中读取的数据高达 1MB,因此如果不进一步阅读就无法窥视整个数据。

4

1 回答 1

2

您可以创建自己的子类QNetworkAccessManager并覆盖虚函数createRequest。调用基类实现以获取响应对象并将readyRead信号连接到将捕获数据的某个插槽。在该插槽中调用 peek 函数来读取数据,以便 WebKit 也将获取数据:

class NetworkAccessManagerProxy : public QNetworkAccessManager {
Q_OBJECT

signals:

    void dataGot(QByteArray data);

public:
    NetworkAccessManagerProxy(QObject * parent = 0)
         : QNetworkAccessManager()
    {
    }

    virtual QNetworkReply* createRequest(Operation op, const QNetworkRequest& request, QIODevice *outgoingData)
    {
        reply = QNetworkAccessManager::createRequest(op, request, outgoingData);
        connect(this,SIGNAL(readyRead()), SLOT(readInternal()));
        return reply;
    }

private slots:

     void readInternal()
     {
        QByteArray data = reply->peek(reply->bytesAvailable());
        emit dataGot(data);
     }

private:

    QNetworkReply* reply;
};

创建QWebPage对象后,调用setNetworkAccessManager并传递一个新创建的子类实例:

QWebPage * page = new QWebPage; 
page->setNetworkAccessManager(new NetworkAccessManagerProxy());
page->mainFrame()->load(url);

webView->setPage(page);
于 2014-08-05T16:22:46.777 回答