QQuickImageProvider: images are not updated (cache not released ?)
-
Hi,
i need to display .tga files in QML.
i use QQuickImageProvider to load .tga images and it works.
But if i modify the .tga file outside my application and if i try to load it again, the image is not updated.
i have read in this documentation that images returned by a QQuickImageProvider are automatically cached and i need to set "cache:false" property in my qml image.
https://doc.qt.io/qt-5/qquickimageprovider.html#detailsBut it does not work. If i reload the same image, modifications are not displayed.
Here is my QML code:Image { id: idImg width : 256;height:256 cache: false source : "image://TGAImageProvider/C:/temp/image.tga" } Connections { target:cppOwner onNewImageGenerated: { idImg.source = "image://TGAImageProvider/C:/temp/image.tga"; } }
My QQuickImageProvider code is something like that:
QPixmap TGAImageProvider::requestPixmap(const QString &id, QSize *size, const QSize &requestedSize) { QString fileName = id; data = loader.LoadFromFile((char*)fileName.toStdString().c_str(),(unsigned char*)data); if( data == NULL ) { return false; } QImage::Format bpp = QImage::Format_RGB888; // Format RGB if( loader.BPP == 4) bpp = QImage::Format_RGBA8888; // Format RGBA QPixmap pixmap = QPixmap::fromImage( QImage( (unsigned char *) data, loader.width, loader.height, loader.bpp ) ); free(data); data = NULL; return pixmap; }
i use QT 5.8
-
Hi,
i need to display .tga files in QML.
i use QQuickImageProvider to load .tga images and it works.
But if i modify the .tga file outside my application and if i try to load it again, the image is not updated.
i have read in this documentation that images returned by a QQuickImageProvider are automatically cached and i need to set "cache:false" property in my qml image.
https://doc.qt.io/qt-5/qquickimageprovider.html#detailsBut it does not work. If i reload the same image, modifications are not displayed.
Here is my QML code:Image { id: idImg width : 256;height:256 cache: false source : "image://TGAImageProvider/C:/temp/image.tga" } Connections { target:cppOwner onNewImageGenerated: { idImg.source = "image://TGAImageProvider/C:/temp/image.tga"; } }
My QQuickImageProvider code is something like that:
QPixmap TGAImageProvider::requestPixmap(const QString &id, QSize *size, const QSize &requestedSize) { QString fileName = id; data = loader.LoadFromFile((char*)fileName.toStdString().c_str(),(unsigned char*)data); if( data == NULL ) { return false; } QImage::Format bpp = QImage::Format_RGB888; // Format RGB if( loader.BPP == 4) bpp = QImage::Format_RGBA8888; // Format RGBA QPixmap pixmap = QPixmap::fromImage( QImage( (unsigned char *) data, loader.width, loader.height, loader.bpp ) ); free(data); data = NULL; return pixmap; }
i use QT 5.8
@Greg13 Yeah. There's an image cache (I think more of a texture cache) inside QML.
The key is the URL. Several of my slightly weird apps, notably my pixel painter hit this and I had to work around it. You'll probably notice that your loader isn't even invoked if image.source is assigned the value already in image.source.
The thing to do is to keep a "cache key" and append that to the URL. It doesn't actually matter what it is (time might be a good example or a monotonically incrementing counter). Your loader can ignore it but it means that the URL differs and thus you won't pick up cached "duff" values.
I have some demo code I can upload to GitHub but please forgive the quality of it as I haven't had time to finish it to my satisfaction. It is actually based on getting an image from the camera to an SQLITE table and back again but shows some of the principles.
-
cache: false
does indeed prevent to cache image textures.
Your problem is that you don't actually change the source of the image so the engine doesn't know that it has to reload it.To force a change you could do:
Connections { target:cppOwner onNewImageGenerated: { idImg.source = ""; idImg.source = "image://TGAImageProvider/C:/temp/image.tga"; } }
-
cache: false
does indeed prevent to cache image textures.
Your problem is that you don't actually change the source of the image so the engine doesn't know that it has to reload it.To force a change you could do:
Connections { target:cppOwner onNewImageGenerated: { idImg.source = ""; idImg.source = "image://TGAImageProvider/C:/temp/image.tga"; } }
@GrecKo I haven't used this property and I'm not quite sure what the docs imply.
"Setting cache to false is useful when dealing with large images, to make sure that they aren't cached at the expense of small 'ui element' images."
Does this mean no caching at all or does it mean that the image is not cached only in texture memory? I'm not sure.