Qt: Что испустить при вставке элементов в мою модель, чтобы намекнуть на представление, чтобы перепроверить canFetchMore? - PullRequest
0 голосов
/ 25 июня 2018

У меня есть пользовательская модель (расширяет QAbstractTableModel), где данные строк добавляются прагматично.Из соображений производительности я использую функцию выборки (canFetchMore, fetchMore), чтобы избежать задержки пользовательского интерфейса, когда элементы не видны.

Когда вставляется новая строка, я не хочу запускать QAbstractItemModel::rowsInserted.Но если эти строки будут видны на виде, я бы хотел, чтобы они появлялись автоматически.Они появляются, если пользователь взаимодействует с представлением, например, выбирая последний элемент (представление вызывает 'canFetchMore' и будет вызывать fetchMore, только если эти элементы будут видны).

Как передать сигналпоказать, что для отображения доступно больше строк, но их нужно выбрать?

1 Ответ

0 голосов
/ 05 июля 2018

Решение для 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 определяет вашу проблему ...)

...