Images in GridView re-caching on filtering
-
I'm implementing some kind of game library. There
GridView
operating with C++ model which contains boxart image that should be displayed in GridView's delegate.Images fetched from backend to AppData\Local and displaying with no issues (model gives URL to Local).
But there something ugly happens when I use
QSortFilterProxyModel
(as simplest way to implement filter functionality).
When filters applied, as I understand, when delegates is not visible anymoreGridView
releases "cache" of delegates, no meterImage
'scache
is set totrue
. So, when delegate appears again is reloads image again.There part of the code where
GridView
's delegate is implemented:model: appFilterModel delegate: ItemDelegate { width: contentsWidth; height: contentsHeight; property int delegateIndex: index property alias appContextMenu: appContextMenuLoader.item property alias appNameText: appNameTextLoader.item Image { id: appBoxar cache: true asynchronous: true anchors.centerIn: parent source: model.boxart onSourceSizeChanged: { width = contentsWidth - 20 height = contentsHeight - 20 } // Display a tooltip with the full name if it's truncated ToolTip.text: model.name ToolTip.delay: 1000 ToolTip.timeout: 5000 ToolTip.visible: (parent.hovered || parent.highlighted) && (!appNameText || appNameText.truncated) } Loader { ... } ... }
I have tried different approaches to deal with delegate images re-appearance, and there what have I suggested:
1. Just make smooth Image appearance when loaded using
NumberAnimation
2. Somehow cacheImage
outside theGridView
and use it's URL on delegate by index(Use source model for instance). (I have tried with single image on delegates, works just fine).But still feels like I'm doing something wrong. For some point, that
GridView
de-caches delegates have sense.Any suggestions how to improve delegate's
Image
behavior on re-appearance? -
@GrecKo the problem is, that GridView releases it delegates when model's elements is removed. It provokes
Image
to reload if delegate is shown again. No meter if I setcache: true
Such a shame that
GridView
don't havereuseItems
likeListView
I've come with next decision. I've created
Repeater
containingImage
that use source model.GridView
's delegateImage
use Repeater's functionitemAt()
giving delegate's index after mapping to source model://Image in deleagte Image { Component.onCompleted: { source = appModelImages.loadImage(appFilterModel.mapRowToSource(parent.delegateIndex)) // custom implementation } ... } //Repeater Repeater { id: appModelImages visible: false function loadImage(index){ return itemAt(index).source } model: AppModel delegate: Image { visible: false asynchronous: true source: model.boxart } }
This may be not the best decision, but "faster" than create own delegate pool for
GridView
. Didn't see any examples of implementing mechanism like this.Repeater
should work fine, as it relays on source model. And as I expected, images live when source model does.