【发布时间】:2015-03-27 02:58:51
【问题描述】:
我需要将繁重的数据集加载到 QTableView 中。数据集在内存中不小于 700Mb,我不想将其全部加载到内存中。
QSqlQueryModel 对我来说并不理想,原因有两个 - 它不可编辑,也不是真正的按需加载(因为将整个数据提取到内存中)。
我想得到什么
- 我只想在内存中存储部分数据。只为 显示,也许还有一些用于快速滚动的缓冲区。
- 模型应该是可编辑的
- 应该是低内存消耗
- 不应冻结
我是如何解决这个问题的(我的代码的简单模型)
- 自定义 QTableView (tableView)
- 自定义 TableModel(模型)
- 模型包装。 (包装)
模型包装器从数据库中选择行数,并将此值设置为模型。现在模型可以回答 int rowCount()。
为 tableView.verticalScrollBar() 设置了相同的值。
tableView.verticalScrollBar 信号(valueChanged) 连接到tableview slot(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);
}
wrapper::changeOffset 中的_selectQuery 是预先执行的QSqlQuery 游标,用于选择查询结果。
我还在模型中实现了几个方法
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();
}
模型数据存储的设置器
void SqlRecModel::setRecordList(const QList<QSqlRecord> &records)
{
qDebug() << "r:";
emit layoutAboutToBeChanged();
m_recList = records;
emit layoutChanged();
}
问题
我可以滚动 _cacheSize 行,但在退出旧的 cacheRange 后出现崩溃(程序已意外完成。)。
有什么建议吗?我不知道在哪里挖。谢谢!
【问题讨论】:
-
如果发生崩溃:取出调试器并开始找出发生崩溃的位置。
-
你是对的。我正在安装普通调试器的路上。当前一个在 0x0 处显示 ReadAccess 错误。 QSqlRecord Qt5Sql!QSqlRecord::QSqlRecord: 0x675f71d0: mov rax,qword ptr [rdx]
标签: qt