我使用的是 qt5.3,在发布之前我用 google 搜索了很多。
我想从 QNetworkReply
中读取数据。我有一个 QWebView
,我还需要 QWebView
读取 http 响应以显示网页。我需要的只是记录 Web 内容或对 http 帖子的任何响应。
问题是 QNetworkReply
是只能读取一次的东西。
如果我在选择
readyRead()
信号时调用readAll()
,我将获得完整数据。但它将被清除,因此QWebView
不显示任何内容(它不会获得任何回复数据)。或者如果我选择
finished()
信号,因为数据已经被QWebView
(或QNetworkAccessManager
)读取,我如果我在这里调用readAll()
什么也得不到。QNetworkReply
或管理器或任何类是否在某处存储我仍然可以读取的数据?
在 #1 中,如果我调用 peek()
,我可以获得部分数据。该函数不清除响应数据。但如果响应主体很大,它将不起作用。 QNetworkReply
是一个连续的东西,我既不能知道它的数据,也不能读取比缓冲更远的数据。
我不知道该怎么做......
我只想监视和记录在我的 QWebView
上发出的任何请求的请求和响应主体 ...
编辑:请注意,我要从响应中读取的数据大到 1MB,因此如果不进一步阅读就无法查看整个数据。
最佳答案
您可以创建自己的 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);
关于c++ - 如何从 QNetworkReply 读取内容(http 响应正文),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25142614/