Images in GridView re-caching on filtering
-
I'm implementing some kind of game library. There
GridViewoperating 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 anymoreGridViewreleases "cache" of delegates, no meterImage'scacheis 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 cacheImageoutside theGridViewand 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
GridViewde-caches delegates have sense.Any suggestions how to improve delegate's
Imagebehavior on re-appearance? -
I'm implementing some kind of game library. There
GridViewoperating 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 anymoreGridViewreleases "cache" of delegates, no meterImage'scacheis 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 cacheImageoutside theGridViewand 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
GridViewde-caches delegates have sense.Any suggestions how to improve delegate's
Imagebehavior on re-appearance?What is the problem your are experiencing?
Does usingaynchronous: trueandcache: truein the Image fixes it? -
What is the problem your are experiencing?
Does usingaynchronous: trueandcache: truein the Image fixes it?@GrecKo the problem is, that GridView releases it delegates when model's elements is removed. It provokes
Imageto reload if delegate is shown again. No meter if I setcache: trueSuch a shame that
GridViewdon't havereuseItemslikeListViewI've come with next decision. I've created
RepeatercontainingImagethat use source model.GridView's delegateImageuse 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.Repeatershould work fine, as it relays on source model. And as I expected, images live when source model does.