Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Qt:在我的模型中插入项目以提示视图重新检查canFetchMore时要发出什么?_Qt_Qtableview_Qabstractitemmodel_Qabstracttablemodel_Qabstractitemview - Fatal编程技术网

Qt:在我的模型中插入项目以提示视图重新检查canFetchMore时要发出什么?

Qt:在我的模型中插入项目以提示视图重新检查canFetchMore时要发出什么?,qt,qtableview,qabstractitemmodel,qabstracttablemodel,qabstractitemview,Qt,Qtableview,Qabstractitemmodel,Qabstracttablemodel,Qabstractitemview,我有一个自定义模型(extendsQAbstractTableModel),其中实际添加了行数据。出于性能方面的原因,我正在使用fetch功能(canFetchMore,fetchMore)来避免项目不可见时的UI延迟 插入新行时,我不想触发qabstractemmodel::rowsInserted。但是如果这些行在视图中可见,我希望它们自动显示。如果用户与视图交互,例如选择最后一个项目(视图调用“canFetchMore”,并且仅当这些项目可见时才会调用fetchMore) 如何向视图发出信

我有一个自定义模型(extends
QAbstractTableModel
),其中实际添加了行数据。出于性能方面的原因,我正在使用fetch功能(
canFetchMore
fetchMore
)来避免项目不可见时的UI延迟

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


如何向视图发出信号,显示更多行,但需要提取?

Qt 5.6.1解决方案-未测试其他版本

在深入研究了
qabstractemview
的源代码后,我发现触发
fetchMore
的最简单方法是启动
qabstractemviewprivate的
内部和未记录的
fetchMoreTimer

这严重依赖于实现,在未来的Qt版本中可能会发生变化

子类化您的
qabstractemview
派生(例如
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()

编辑

可以重写
行插入(…)
,并且只有在新添加的行可见时才调用基本实现。
但这似乎也很困难

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

我唯一的想法是在第一个
n
项上发出
rowsInserted
,然后让视图稍后获取更多,但是,用户的视图可能有超过
n
项的空间。您确定标准视图不会忽略上次获取的行以外的
rowsInserted
。垂直标题为每个插入添加了节(行),但数据查找返回空数据(因为MyModel::index()提供了无效的索引,这是正确的)。但除了添加额外的空行之外,最终还会发生崩溃。您是否正确使用了
beginInsertRows()
endInsertRows()
?我想剩下的事情会自动发生。@MartinHennings,是的。如果我正确插入行(其中发出的行对应于我的内部数据结构),视图将始终显示它们,并且
canFetchMore
将始终返回false。我看到了计时器,并同意您所说的一切。我不是这个解决方案的超级粉丝,但它可能是最强大的。如果计时器可以直接启动,我会说这是一个很好的答案。@jtooker
我不是这个解决方案的超级粉丝
-我也是。如果您已经需要对
qabstractemview
进行子类化,还可以手动检查是否需要更新。您可以覆盖
行插入()
,请参阅编辑我的答案。