qt – 何时或如何在QSqlTableModel上使用fetchMore()并使用SQLit
我的类DataTable派生自QAbstractTableModel.它在内部使用QSqlTableModel对象从db表中获取数据.它表示db中每一行的记录(它执行的操作更多,但记录计数始终是db表中的行数).
使用MySql,我的DataTable :: rowCount()实现只调用QSqlTableModel上的rowCount(),这很好用. 现在使用SQLite,如果db表中有超过256行,Qt的SQLite驱动程序返回的行数为256,因此我的DataTable类也返回256 – 这是错误的. documentation告诉我调用while(sql_model-> canFetchMore())sql_model-> fetchMore();.在创建内部QSqlTableModel之后立即调用fetchMore()实际上会导致以下rowCount()调用返回正确的值.但是一旦数据库中的某些内容发生了变化(我的类将在QSqlTableModel上调用insertRow()或setData()),下一个QSqlTableModel :: rowCount()调用将再次返回256. 数据库仅由我的类修改,而我的类又使用该特定的QSqlTableModel对象(或使用我的DataTable作为模型的视图可以更新某些内容).因此,没有其他进程可以将行插入数据库. 那么我的DataTable类何时应该为rowCount()调用fetchMore()以始终返回实际的行数? 更新: 这里有一些代码来演示基本问题. QSqlTableModel *model = new QSqlTableModel(0,database); //QSqlDatabase model->setTable("tablename"); qDebug() << "0 row count" << model->rowCount(); //0 row count 0 model->setEditStrategy(QSqlTableModel::OnManualSubmit); model->select(); qDebug() << "1 row count" << model->rowCount(); //1 row count 256 while (model->canFetchMore()) model->fetchMore(); qDebug() << "2 row count" << model->rowCount(); //2 row count 1520 //... other methods ... model->setData(model->index(0,0),"TEST"); model->submitAll(); qDebug() << "3 row count" << model->rowCount(); //3 row count 256 while (model->canFetchMore()) model->fetchMore(); qDebug() << "4 row count" << model->rowCount(); //4 row count 1520 加载sql模型后,rowCount()返回256(1),因此必须调用fetchMore().然后rowCount()返回实际的行数. 因此,似乎必须在sql模型上的每次写操作之后调用fetchMore().但是,而不是在修改模型的每个方法的末尾放置/ canFetchMore()/ fetchMore()循环,我想知道是否足以连接beforeInsert(QSqlRecord&),beforeUpdate(int,QSqlRecord& )和beforeDelete(int)发信号到一个槽,然后调用fetchAll()?这是否可靠和合适? 更正:不在*信号之前(太早),但可能是layoutChanged(),dataChanged(),rowsInserted()和rowsRemoved(). 更新2: 关于SQL的注意事项:我知道我可以在理论上向数据库发送单独的SELECT COUNT SQL查询,但这不能回答这个问题.只要我能避免SQL,我就不会编写SQL.在我看来,发送这样一个SQL查询违背了面向对象的QAbstractTableModel类的目的.另外rowCount()是const(不应该发送查询),应该很快.无论如何,这不会修复rowCount(). 我最终将一个调用fetchMore()的插槽连接到相关信号(见上文)并断言所有内容都已在rowCount()中获取: 这是因为rowCount()无法报告正确的行计数对我来说是故障状态,因此断言.换句话说,我宁愿让我的应用程序崩溃而不是使用不正确的行数. 只需将它连接到dataChanged()信号(如first answer中所述:我可能会尝试使用dataChanged信号.)是不够的.我已将它连接到dataChanged(const QModelIndex&,const QModelIndex&),rowsInserted(const QModelIndex&,int,int),rowsRemoved(const QModelIndex&,int)和layoutChanged(). 似乎工作,断言还没有失败. 如果有人能够明确证实这一点(或解释为什么它不会一直有效),我会很感激答案. 根据我的经验,Qt的SQLite驱动程序以256行的步长将行插入到模型中.在数据提取结束时,QSqlTableModel :: rowCount()将返回正确的值,因此无需调用fetchMore().它只取决于你在何时何地调用rowCount().例如,如果用户正在对rowsInserted()信号进行一些计算,则他的插槽方法将被多次调用,并且每次最后一行的索引将递增最多值256. 因此,您需要在数据提取结束时使用rowCount()(在某些重写的QSqlTableModel方法中,提取通常不会完成),或者不依赖于中间行计数值并在每次更改时重复计算. 这是一般答案,因为您没有发布任何代码,我们可以看到您正在尝试做什么,但您可以看到我指向的位置. 编辑: 在调用QSqlTableModel :: submitAll()之后,重新填充模型,这就是为什么需要再次重复fetchMore()的原因.调用fetchMore()的位置取决于用例.它可以在submitAll()之后调用,或者在某个插槽中,这里没有一般答案.我可能会尝试使用dataChanged信号.但是,获取数据的目标始终应该是主要的,以便在视图中显示它,并且视图在大多数情况下自行完成. 在我的一个应用程序中,我依靠表视图来为我提取数据.在将模型设置为表视图后,我要么调用QTableView :: scrollToBottom()为我提取数据(用户应该在我的情况下看到底部的最新数据,滚动后行数有正确的值)或者在rowsInserted中进行计算当用户滚动表时,()插槽,并再次以256行的步长自动获取数据. 并且非常重要的是要知道,如果应用程序需要在表格中显示某些行数,或者例如一个列数据的汇总值,使用额外的QSqlQuery来获取其他信息(如:从xyz中选择count(*))然后从大型表模型中读取数据通常要高效得多.表模型主要用于向表视图提供数据. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |