2011-12-13 213 views
0

我需要一個表格GUI控件,它能夠快速添加和顯示大約100'000個項目。 因此,需要「虛擬」表格控件,該控件僅加載和顯示僅可見項目。 我試圖QTableView中和QAbstractTableModel:QAbstractTableModel :: data方法被調用的次數太多

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 ::數據()增加新的項目了可視面積時被調用。這使得性能下降很慢。 這是我的測試場景更具體:

  1. 查看是創建只有5個元素,可以在一次可見。
  2. 我用MyModel :: addItems添加了20個項目。
  3. MyModel :: data是爲所有可見項目調用的。
  4. 添加項目6,7,9 ... 20時,繼續爲可見項目(1 ... 5)調用MyModel :: data。

我在想也許這可能是由於添加新項目時重繪的垂直滾動條引起的,並且似乎使所有QListView重繪。但隱藏垂直滾動條後,問題依然存在。 請建議。

回答

1

我沒有找到如何防止endInsertRows調用導致額外調用data()方法。但是爲多個項目調用endInsertRows解決了性能問題。因此,我呼籲:

beginInsertRows(QModelIndex(), rowCount(), rowCount() + 1000); 
endInsertRows(); 

,而不是調用1000次:

beginInsertRows(QModelIndex(), rowCount(), rowCount()); 
endInsertRows(); 
0

dataSource-> cell()實現的漸近複雜性是什麼? data()可能確實被調用很多次,甚至更多,如果你把例如頂部的QSortFilterProxyModel用於排序。爲了確保具有大量數據的項目視圖的性能,data()必須僅需要恆定的時間來實現。