我需要一个表GUI控件,能够快速添加和显示大约100'000个项目。 出于这个原因,需要“虚拟”表控件,它只加载和显示可见项。 我尝试了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()。这使得性能大幅下降。 这是我更具体的测试场景:
我想也许这可能是由添加新项目时重绘的垂直滚动条引起的,并且似乎使所有QListView重绘。但在隐藏垂直滚动条之后,问题仍然存在。 请建议。
答案 0 :(得分:2)
我没有找到如何防止endInsertRows调用导致额外调用data()方法。但是为多个项调用endInsertRows一次可以解决性能问题。所以我打电话给:
beginInsertRows(QModelIndex(), rowCount(), rowCount() + 1000);
endInsertRows();
而不是要求1000次:
beginInsertRows(QModelIndex(), rowCount(), rowCount());
endInsertRows();
答案 1 :(得分:0)
dataSource-> cell()实现的渐近复杂性是什么? data()确实可能被调用很多次,如果你把例如更多顶部的QSortFilterProxyModel用于排序。为了确保具有大量数据的项目视图的性能,data()必须只需要恒定的时间来实现。