2

我有一个自定义模型(扩展QAbstractTableModel),其中行数据被务实地添加。出于性能原因,我使用获取功能 ( canFetchMore, fetchMore) 来避免当项目不可见时 UI 滞后。

插入新行时,我不想触发QAbstractItemModel::rowsInserted. 但如果这些行在视图中可见,我希望它们自动出现。如果用户与视图交互,它们会出现,例如选择最后一个项目(视图调用“canFetchMore”并且fetchMore仅当这些项目可见时才会调用)。

我如何向视图发出信号,表明有更多行可供显示,但需要获取?

4

1 回答 1

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 代码中的注释如何指出您的问题......)

于 2018-07-05T11:12:03.197 回答