QAbstractTableModel::data方法调用次数过多
QAbstractTableModel::data method is called too many times
我需要一个表GUI控件,能够快速添加和显示大约10万项。出于这个原因,需要"虚拟"表控件,它只加载和显示可见的项。我尝试了QTableView和QAbstractTableModel:
class MyModel : public QAbstractTableModel
{
public:
MyModel(QObject * parent, IDataSource* dataSource)
: QAbstractTableModel(parent), m_dataSource(dataSource) {}
int rowCount(const QModelIndex& parent = QModelIndex()) const
{
return m_dataSource->rowCount();
}
int columnCount(const QModelIndex& parent = QModelIndex()) const
{
return 3;
}
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const
{
if (role == Qt::DisplayRole)
{
return m_dataSource->cell(index.row(), index.column());
}
return QVariant();
}
bool addItem()
{
beginInsertRows(QModelIndex(), rowCount(), rowCount());
endInsertRows();
return true;
}
private:
IDataSource* m_dataSource;
};
...
MyModel* model = new MyModel(this, this);
m_ui.tableView->setModel(model);
m_ui.tableView->show();
问题是MyModel::data()在添加新项目到可见区域时被调用。这使得性能大大降低。下面是更具体的测试场景:
- 视图一次只能显示5个元素
- 我用MyModel::addItems添加了20个项目。
- MyModel::data被所有可见的项目调用。
- MyModel::data继续被调用为可见的项目(1…5),当项目6,7,9…
我想也许这可能是由于添加新项目时重新绘制的垂直滚动条引起的,并且似乎使所有QListView重新绘制。但是在隐藏垂直滚动条之后,这个问题仍然存在。请建议。
我不知道如何防止endInsertRows调用导致对data()方法的额外调用。但是对多个项目调用一次endInsertRows可以解决性能问题。所以我调用:
beginInsertRows(QModelIndex(), rowCount(), rowCount() + 1000);
endInsertRows();
而不是调用1000次:
beginInsertRows(QModelIndex(), rowCount(), rowCount());
endInsertRows();
您的dataSource->cell()实现的渐近复杂性是多少?data()确实可能被调用很多次,如果你在上面放一个QSortFilterProxyModel来排序,甚至会调用更多。为了确保具有大量数据的项视图的性能,data()必须只需要恒定的时间来实现。
相关文章:
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 函数调用中参数的顺序重要吗
- OpenGL - 在抛出"__gnu_cxx::recursive_init_error"实例后终止调用?
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 在c++类上调用void函数
- 为什么 std::unique 不调用 std::sort?
- 调用专用模板时出错"no matching function for call to [...]"
- 在向量上调用 clear() 实际上不会删除 data() 中的数据?
- QabstractListModel :: Data()方法从未被调用
- 为什么valgrind(helgrind)在我的线程结构上调用虚函数时生成"Possible Data Races"
- glDrawArrays 之间的 glBufferSubData 调用 mangling data
- qt QStandardItemModel data() 未被调用
- STL Vector:临时调用 data() 时的未定义行为
- QAbstractTableModel::data方法调用次数过多
- 当你在 std::vector 上调用 data() 时会发生什么<bool>?
- QAbstractItemModel data()永远不会被调用
- 从特定位置调用Upper_bound函数,而不是使用data.begin()