QTableView +自定义TableModel +延迟加载

时间:2015-01-28 09:12:48

标签: qt

我需要将大量数据集加载到QTableView中。数据集在内存中不低于700Mb,我不想将其全部加载到内存中。

QSqlQueryModel对我来说并不理想,原因有二:它不可编辑,并且不是按需加载(因为将整个数据提取到内存中)。

我想要的是什么

  • 我想只将部分数据存储在内存中。只为 显示并可能有一些缓冲区用于快速滚动。
  • 模型应该是可编辑的
  • 应该是低内存消耗
  • 应该没有冻结

我是如何解决此问题(我的代码的简单模型)

  1. 自定义QTableView(tableView)
  2. 自定义表模型(模型)
  3. 模型包装器。 (包装)
  4. 模型包装器从数据库中选择行数,并将此值设置为model。现在模型可以回答int rowCount()。

    为tableView.verticalScrollBar()设置了相同的值。

    tableView.verticalScrollBar信号(valueChanged)连接到tableview插槽(on_valueChanged)

    部分代码

    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 :: changeOffset是用于选择查询结果的PRSqlQuery游标。

    我还在模型中实现了几种方法

    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

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

    问题

    我可以滚动_cacheSize行,但是在离开旧的cacheRange后我崩溃了(程序意外地完成了。)

    有什么建议吗?我不知道在哪里挖。谢谢!

1 个答案:

答案 0 :(得分:0)

抱歉令人不安。

其他代码块出错。

这种方式可以解决我的任务。

btw:如果您使用缓存缓冲区,则可以实现更流畅的滚动。