Qt: Что испустить при вставке элементов в мою модель, чтобы намекнуть на представление, чтобы перепроверить canFetchMore?
У меня есть кастомная модель (расширяет QAbstractTableModel
) где данные строки добавляются прагматично. Из соображений производительности я использую функцию извлечения (canFetchMore
, fetchMore
), чтобы избежать задержки интерфейса, когда элементы не видны.
Когда новая строка вставлена, я не хочу, чтобы вызвать QAbstractItemModel::rowsInserted
, Но если эти строки будут видны на виде, я бы хотел, чтобы они появлялись автоматически. Они появляются, если пользователь взаимодействует с представлением, например, выбирая последний элемент (представление вызывает 'canFetchMore' и будет вызывать fetchMore
только если эти предметы будут видны).
Как я могу сигнализировать представлению, что больше строк доступно для отображения, но их нужно извлечь?
1 ответ
Решение для Qt 5.6.1 - не протестировано для других версий!
Покопавшись в источниках QAbstractItemView
Я нашел самый простой способ вызвать fetchMore
это начать QAbstractItemViewPrivate's
внутренний и недокументированный fetchMoreTimer
,
Это сильно зависит от реализации и может измениться в будущих версиях Qt!
Подкласс ваш QAbstractItemView
дериват (например, QListView
,...) чтобы получить доступ к одной из защищенных функций запуска таймера:
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;
}
}
};
Теперь, после добавления предметов в вашу модель, вы можете позвонить view->CheckFetchMore();
редактировать
Может быть возможно переопределить rowsInserted(...)
и вызывать базовую реализацию, только если добавленные строки будут видны.
Но это тоже кажется клёвым.
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);
}
(Мне нравится, как комментарий в коде Qt определяет вашу проблему...)