Solution for Qt 5.6.1 - untested for other versions!
After digging around in the sources of QAbstractItemView
, I found the simplest way to trigger fetchMore
is to start the QAbstractItemViewPrivate's
internal and undocumented fetchMoreTimer
.
This is heavily implementation dependent and may change in future Qt versions!
Subclass your QAbstractItemView
derivate (e.g. QListView
, ...) to get access to one of the protected functions starting the timer:
class CFetchMoreListView : public QListView
{
Q_OBJECT
public:
explicit CFetchMoreListView(QWidget *parent = Q_NULLPTR)
: QListView(parent)
{ }
inline void CheckFetchMore()
{
int mode = 0;
switch(mode)
{
case 0: // works - but I didn't check how much unneccessary updating it performs
updateGeometries();
break;
case 1: // updates the view allright, but also loads items not currently in view
verticalScrollbarValueChanged(verticalScrollBar()->maximum());
break;
case 2: // needs at least one item already inserted
if(currentIndex().isValid())
{
QModelIndex const curr = currentIndex();
currentChanged(curr, curr);
}
break;
case 3: // leads to flicker
setVisible(false);
rowsInserted(QModelIndex(), 0, 0);
setVisible(true);
break;
}
}
};
Now, after adding items to your model, you can call view->CheckFetchMore();
Edit
It might be possible to override rowsInserted(...)
and only call the base implementation if the newly added rows would be visible.
But that seems kludgy as well.
void QListView::rowsInserted(const QModelIndex &parent, int start, int end)
{
Q_D(QListView);
// ### be smarter about inserted items
d->clear();
d->doDelayedItemsLayout();
QAbstractItemView::rowsInserted(parent, start, end);
}
(I love how the comment in the Qt code pinpoints your problem...)