QDeclarativeImageProvider for caching images on file?
-
If you look at "documentation":http://doc.qt.nokia.com/4.7/qdeclarativeengine.html#networkAccessManager you see that if QNAM was not created by factory returned QNAM will have no proxy or cache set.
So you must use factory.
@
#include <QDeclarativeNetworkAccessManagerFactory>
#include <QNetworkAccessManager>
#include <QNetworkDiskCache>
#include <QDesktopServices>class NAMFactory : public QDeclarativeNetworkAccessManagerFactory
{
public:
QNetworkAccessManager* create(QObject *parent) {
QNetworkAccessManager *nam = new QNetworkAccessManager(parent);QNetworkDiskCache *diskCache = new QNetworkDiskCache(nam); diskCache->setCacheDirectory(QDesktopServices::storageLocation(QDesktopServices::CacheLocation)); diskCache->setMaximumCacheSize(CACHE_SIZE); nam->setCache(diskCache); return nam; }
};@
And then
@qml_engine()->setNetworkAccessManagerFactory(new NAMFactory);@
-
I did read the docs for that method, but it's still returning a reference to a single QNAM so it should be possible to call setDiskCache() on it, right? Anyway, I am now using your NAMFactory implementation (thanks for the providing that by the way) and QML still doesn't seem be using the cache.
Should QML Image elements (for example) automagically use the cache rather than making a network request? It would be great if it worked that way but it all sounds way too straight forward to me ;-)
-
[quote author="pdrummond" date="1304594266"]I did read the docs for that method, but it's still returning a reference to a single QNAM so it should be possible to call setDiskCache() on it, right?[/quote] But you don't know how QNAM was created...
[quote]Anyway, I am now using your NAMFactory implementation (thanks for the providing that by the way) and QML still doesn't seem be using the cache.[/quote]
I don't know why, but you must set nam factory before loading qml file(s). It's working for me.
[quote]
Should QML Image elements (for example) automagically use the cache rather than making a network request? It would be great if it worked that way but it all sounds way too straight forward to me ;-)[/quote]Image element doesn't know if image is loaded from cache or network. That's the job of QNAM and QNetworkDiskCache. Image element will make network request, which would go through QNAM, and QNetworkDisckCache will check if image is in the cache, if not, it will be loaded through network, otherwise QNAM will return image from cache. -
Thanks for explaining - it all makes sense. I do set the factory before loading the main QML file but it's still not working for me. When I disconnect the wifi on my development machine I get the following error on the QML Image element:
@
QML QDeclarativeImage_QML_24: Host xxx.co.uk not found
@which sounds like it's ignoring the cache. Do you know if there are any settings or flags that need to be set on QNAM? I see from the QNetworkDiscCache docs that in C++ it is necessary to configure QNetworkRequests as follows:
@
request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
@I assume QML does this by default?
-
I just tested my application...
There is a big listview of with 200 images elements (all downloaded from network). WiFi is turned on. Next, I have done scrolling through list, so that images are cached. Now, WiFi is turned off. Images that were instanced in listview are showed. So image caching is working.
I don't know where is your problem, but I would check what is the cache directory, and see if directory is created (if not, you should create the directory in NAMFactory). If directory is created there should be some cache files.
-
Hmmm. I think the caching you are seeing when you scroll is not the Disk Cache. I'm sure I have been able to do the same scroll test without having a Disk Cache in place. I will test that again to be sure...
A better test would be to have a ListView where the items are locally sourced but they include an image that is loaded from the network. When you run the app for the first time, the images will be downloaded, then you shut down the app, turn wifi off, re-run the app and the images should still be displayed because they are automatically sourced from the disk cache.
-
[quote author="pdrummond" date="1304604386"]
A better test would be to have a ListView where the items are locally sourced but they include an image that is loaded from the network. When you run the app for the first time, the images will be downloaded, then you shut down the app, turn wifi off, re-run the app and the images should still be displayed because they are automatically sourced from the disk cache. [/quote]
That was the test. And not by turn wifi off, I unplugged adsl modem. :) I am pretty sure caching is working.And the cache is in C:\Users\myusername\AppData\Local\cache on Win7.
-
Do your images load if you turn off WiFi then run the app?
-
What I have been telling you, :) they load. Cache folder exists with http, https, prepaped folders. In http folder there are cache files cache_*.cache. Cache items contains the header and the compressed image (but I don't think images are compressed).
-
Sorry, I just couldn't tell from your posts whether your tests were the same as mine. I am going to write a simple test case and maybe file a bug report on this. Caching simply doesn't work for me :-(
-
Sorry to hear that caching for you doesn't work.
What's the cache directory? Is it created?
-
Hey, did you get this to work? I would really appreciate the solution! Thanks!
-
[quote author="jkosonen" date="1313401377"]Hey, did you get this to work? I would really appreciate the solution! Thanks![/quote]
It's working for me see https://github.com/minimoog/qtwitdget/blob/master/namfactory.h
-
I talked to some of the Qt Dev's on IRC and they were very helpful. In the end it was clear that QNetworkDiskCache isn't designed to solve this problem.
So I had no other choice than to hack together my own CachedImage class in C++. I can't make the code available as it was done for a client and also the code is very specialised and not very clean. But if anyone is doing the same thing and have any questions on my implementation I'd be happy to answer them here.
-
[quote author="pdrummond" date="1313407193"]I talked to some of the Qt Dev's on IRC and they were very helpful. In the end it was clear that QNetworkDiskCache isn't designed to solve this problem.
So I had no other choice than to hack together my own CachedImage class in C++. I can't make the code available as it was done for a client and also the code is very specialised and not very clean. But if anyone is doing the same thing and have any questions on my implementation I'd be happy to answer them here.[/quote]
I would like to have that kind of an solution, but no idea where to start. Shame that you can't publish the code..
-
[quote author="pdrummond" date="1313407193"]I talked to some of the Qt Dev's on IRC and they were very helpful. In the end it was clear that QNetworkDiskCache isn't designed to solve this problem.
So I had no other choice than to hack together my own CachedImage class in C++. I can't make the code available as it was done for a client and also the code is very specialised and not very clean. But if anyone is doing the same thing and have any questions on my implementation I'd be happy to answer them here.[/quote]
Did you do your own QAbstractnetworkCache or?