[solved] Lazy unloading in QAbstractItemModel / QTableView
maybe you came across the same question of mine in the mailing list but I used a different wording there and didn't become an answer so far ;-)
Besides not every visitor of this site has subscribed for one of the lists.
Inside my application I am using a QTableView with a derived QAbtractItemModel. A typical data model can have 10000 and more rows, every 15th of it (average) contains image data that is loaded via QRunnable, because loading tends to be slow and every image must be scaled down.
So far so good or in other words: the model uses lazy loading, the UI is responsive all the time.
But there are negative side effects: when the user scrolls down from top of the table down to the last row, each and every image is loaded one after another and this can take up to three minutes (as I said, it's slow).
But wait, why should I load every image at all? There are more or less only 2-3 images (if at all) visible at the same time. All loading tasks from data that has scrolled outside the viewport could (and should IMHO) be cancelled. Already loaded data can be released to minimize the memory footprint (not so much a problem on a desktop but think mobile).
One question remains: how do I know that data has scrolled outside the viewport and is not visible = not needed anymore?
Is there a signal I have missed?
Or can't I see the wood for all the trees?
Thanks and regards
I'm having the same question in this thread: http://qt-project.org/forums/viewthread/31615/
Ha, almost at the same time :-)
I have subscribed to your thread - just to be sure to not miss an answer.
Maybe you could use QAbstractItemView::visualRect to check whether the item is visible before loading the image ?
Hope it helps
the problem is not when to load an image?
I want to know when I can get rid of it.
But maybe I can get the info this way, i will try... :-)
Solved it this way:
Subclassed QTableView and therein overridden verticalScrollbarValueChanged
void QTableViewSourceSongs::verticalScrollbarValueChanged(int value)
// do whatever the original implementation does
// should never happen
if(value == this->oldScrollBarValue)
QModelIndex newTopLeftIndex = indexAt(this->rect().topLeft());
QModelIndex newBottomLeftIndex = indexAt(this->rect().bottomLeft());
QModelIndex invisibleIndex = (value > this->oldScrollBarValue) ? this->oldTopLeftIndex : this->oldBottomLeftIndex;
auto genericSongModel = static_cast<GenericSongsModel*>(this->model());
this->oldTopLeftIndex = newTopLeftIndex;
this->oldBottomLeftIndex = newBottomLeftIndex;
this->oldScrollBarValue = value;