PDA

View Full Version : using QWebView cache with QNetworkDiskCache



Jann3
28th September 2009, 16:20
So hey Im completely new to QT, and hopefully this is an obvious problem.

What Im trying to do is cache my webpages and retrieve them from the cache. Caching itself seems to works ok - meaning .cache files are created everytime I load a webpage.

However Im not sure how to go about loading from the cache, any ideas?




manager = new QNetworkAccessManager();
diskCache = new QNetworkDiskCache();

QString location = QDesktopServices::storageLocation(QDesktopServices ::CacheLocation);
diskCache->setCacheDirectory(location);
manager->setCache(diskCache);
ui->webView->page()->setNetworkAccessManager(manager);
ui->webView->page()->settings()->setMaximumPagesInCache(10);

request = QNetworkRequest();
request.setAttribute(QNetworkRequest::CacheLoadCon trolAttribute, QNetworkRequest::AlwaysCache);
request.setUrl(QUrl("http://www.qtcentre.org"));

ui->webView->load(request);



Any help would be appreciated.

wysota
28th September 2009, 18:08
QNetworkAccessManager will take care of it itself.

Jann3
7th October 2009, 11:23
So, an update on this. Now Im using handling the requests better, but whichever way I try and load the files inside a webview, all the relative URL's break after the files have been cached, which you can imagine destroys 90% of websites, CSS and images.

Here's a fully bodged together code example.

mainwindow.cpp


#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtNetwork>
#include <QHttpRequestHeader>
#include <QDesktopServices>

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);

QNetworkDiskCache *diskCache = new QNetworkDiskCache(this);
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
manager = ui->webView->page()->networkAccessManager();
websiteUrl = QUrl("http://www.jann3.com/");

QString location = QDesktopServices::storageLocation(QDesktopServices ::CacheLocation);
diskCache->setCacheDirectory(location);
manager->setCache(diskCache);
qDebug() << diskCache->cacheSize();
ui->webView->page()->setNetworkAccessManager(manager);
ui->webView->page()->settings()->setMaximumPagesInCache(10);
ui->webView->page()->settings()->setAttribute(QWebSettings::AutoLoadImages,true);
ui->webView->page()->settings()->setAttribute(QWebSettings::JavascriptEnabled,true) ;

request = QNetworkRequest();
request.setAttribute(QNetworkRequest::CacheLoadCon trolAttribute, QNetworkRequest::PreferCache);
request.setUrl(websiteUrl);

connect(manager, SIGNAL(finished(QNetworkReply*)),this, SLOT(replyFinished(QNetworkReply*)));
manager->get(request);
}

MainWindow::~MainWindow()
{
delete ui;
}

void MainWindow::replyFinished(QNetworkReply* reply)
{
QByteArray data=reply->readAll();
QString str(data);

qDebug() << "---------------------------------------------------";
qDebug() << "Size:" << data.size();
qDebug() << "Item Url:" << reply->url().toString();
qDebug() << "Content Type:" << reply->header(QNetworkRequest::ContentTypeHeader).toStrin g();
QVariant fromCache = reply->attribute(QNetworkRequest::SourceIsFromCacheAttrib ute);
qDebug() << "Item from cache?" << fromCache.toBool();
qDebug() << "File Last Modified:" << reply->header(QNetworkRequest::LastModifiedHeader).toStri ng();

if(reply->url()==websiteUrl)
{
qDebug() << "Attempting render..";
/*
// different methods tried
ui->webView->setContent(data);
ui->webView->setContent(data,QString("text/html"),reply->url());
ui->webView->setContent(data,reply->header(QNetworkRequest::ContentTypeHeader).toStrin g(),reply->url());
ui->webView->setHtml(str,reply->url());
*/
ui->webView->setHtml(str,reply->url());
}
}



mainwindow.h


#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QtGui/QMainWindow>
#include <QtNetwork>

namespace Ui
{
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
MainWindow(QWidget *parent = 0);
~MainWindow();

private slots:
void replyFinished(QNetworkReply*);

private:
QUrl websiteUrl;
//QNetworkAccessManager *manager;
//QNetworkDiskCache *diskCache;
QNetworkRequest request;
Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H


mainwindow.ui
contains a QWebView widget named webView.


Now for the strange part.
From the debugging info you can see the page and it's linked elements still have valid URL requests AND are being found in the cache, so the reason for them not rendering correctly is a complete mystery.

yan
7th October 2009, 13:23
hi.
To use it, i do something like



QNetworkDiskCache *diskCache = new QNetworkDiskCache(this);
diskCache->setCacheDirectory("path cache");
webView->page()->networkAccessManager()->setCache(diskCache );


If you want to use the same cache folder for more of one networkAccessManager, you should shared a QNetworkDiskCache between each networkAccessManager instance.

You can find different WebAttribute about cache, but i never understand how use these.