Artem E
Artem E

Reputation: 367

QTableView + custom TableModel + lazy loading

I need to load heavy dataset into QTableView. Dataset is no less then 700Mb in memory and I don't want to load all it to memory.

QSqlQueryModel is not ideal for me for 2 reasons - it is not editable and it is not realy load-on-demand (because fetching whole data to memory).

What I want to get

How I am trying to solve this (straightforward model of my code)

  1. Custom QTableView (tableView)
  2. Custom TableModel (model)
  3. Model wrapper. (wrapper)

Model wrapper select rows count from database, and set this value to model. Now model can answer for int rowCount().

This same value is set for tableView.verticalScrollBar().

tableView.verticalScrollBar signal(valueChanged) is connected to tableview slot(on_valueChanged)

Some code

tableView::on_valueChanged(value)
{
  wrapper.changeOffset(value);
}

wrapper::changeOffset(value)
{
  if (_offset == value){
    return;
  }

  _selectQuery->seek(value);    
  int endValue = qMin(value + _cacheSize, model->rowCount());  
  _list.clear();
  for(int i = value; i < endValue-1; i++){      
    _list.append(_selectQuery->record());
  }
  model->setRecordList(_list);
  _offset = value;
  model->setOffset(_offset);

}

_selectQuery in wrapper::changeOffset is previosly executed QSqlQuery cursor for select query results.

I also implemented several methods in model

QVariant SqlRecModel::data(const QModelIndex &index, int role) const
{
    int row = index.row() - _offset;        
    if (row > m_recList.size() || row < 0){
        return QVariant();
    }
    if (role == Qt::DisplayRole)
    {
        QVariant value = m_recList.at(row).value(index.column());
        return value;
    }
    return QVariant();
}

Setter for model data storage

void SqlRecModel::setRecordList(const QList<QSqlRecord> &records)
{
    qDebug() << "r:";
    emit layoutAboutToBeChanged();
    m_recList = records;
    emit layoutChanged();
}

Problem

I can scroll _cacheSize rows, but I get crash (The program has unexpectedly finished.) after going out of old cacheRange.

Any advice? I don't know where to dig. Thanks!

Upvotes: 7

Views: 2831

Answers (1)

Artem E
Artem E

Reputation: 367

Sorry for disturbing.

Error was in other code block.

This way is just okay to solve the task I have.

btw: if you play with cache buffer you can achive more smooth scroll.

Upvotes: 0

Related Questions