我通过继承QAbstractItemModel实现了一个延迟填充的树视图.实现看起来像:
https://gist.github.com/gnufied/db9c4d805e2bb24d8c23
(我没有粘贴代码内联,以免混淆消息)
它基本上是存储在表中的分层数据的树表示.现在,我希望用户能够根据列对行进行排序.列是"计数"或"引用计数".这些值基本上是整数.
实现自己的工作,直到我抛出QSortFilterProxyModel,我开始在视图中获得大量空行.难的问题是,只有当我有很多行(大概数千个)时才会发生这种情况.
实现排序代理的代码是:
rootItem = RBKit::SqlConnectionPool::getInstance()->rootOfSnapshot(snapShotVersion);
model = new RBKit::HeapDataModel(rootItem, this);
proxyModel = new SortObjectProxyModel(this);
proxyModel->setSourceModel(model);
ui->treeView->setModel(proxyModel);
ui->treeView->setSortingEnabled(true);
Run Code Online (Sandbox Code Playgroud)
我有子类QSortFilterProxyModel类,子类实现非常简单:
https://gist.github.com/gnufied/115f1a4fae3538534511
文件确实说 -
"对于具有更复杂行为的源模型,可能需要覆盖此简单代理机制;例如,如果源模型提供自定义hasChildren()实现,则还应在代理模型中提供一个."
但除此之外,我不确定 - 我错过了什么.
所以,我认为我已经找到了解决方案,并且修复似乎在代理模型子类中重新实现fetchMore,因为源模型报告的插入行与视图中实际存在的行不匹配(视图中的行由代理模型拥有),所以这似乎已经为我解决了:
#include "sortobjectproxymodel.h"
SortObjectProxyModel::SortObjectProxyModel(QObject *parent) :
QSortFilterProxyModel(parent)
{
}
bool SortObjectProxyModel::hasChildren(const QModelIndex &parent) const
{
const QModelIndex sourceIndex = mapToSource(parent);
return sourceModel()->hasChildren(sourceIndex);
}
int SortObjectProxyModel::rowCount(const QModelIndex &parent) const
{
const QModelIndex sourceIndex = mapToSource(parent);
return sourceModel()->rowCount(sourceIndex);
}
bool SortObjectProxyModel::canFetchMore(const QModelIndex &parent) const
{
if(!parent.isValid())
return true;
else {
const QModelIndex sourceIndex = mapToSource(parent);
return sourceModel()->canFetchMore(sourceIndex);
}
}
void SortObjectProxyModel::fetchMore(const QModelIndex &parent)
{
if (parent.isValid() && parent.column() == 0) {
int row = parent.row();
int startRow = row + 1 ;
const QModelIndex sourceIndex = mapToSource(parent);
RBKit::HeapItem *item = static_cast<RBKit::HeapItem *>(sourceIndex.internalPointer());
if (!item->childrenFetched) {
qDebug() << "Insert New Rows at :" << startRow << " ending at : " << startRow + item->childrenCount();
beginInsertRows(parent, startRow, startRow + item->childrenCount());
item->fetchChildren();
endInsertRows();
}
}
}
Run Code Online (Sandbox Code Playgroud)