gpt4 book ai didi

qt - 何时或如何在 QSqlTableModel 上使用 fetchMore() 和 SQLite 数据库让 rowCount() 工作?

转载 作者:IT王子 更新时间:2023-10-29 06:29:11 26 4
gpt4 key购买 nike

我的类 DataTable 派生自 QAbstractTableModel。它在内部使用 QSqlTableModel 对象从数据库表中获取数据。它代表 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 作为模型的 View ,可以更新某些内容)。所以没有其他进程可以将行插入到数据库中。

那么我的 DataTable 类何时应该为 rowCount() 调用 fetchMore() 以始终返回实际的行数?
我认为我的类(class)应该将 QSqlTableModel 发出的一些信号连接到一个会调用 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() 然后返回实际的行数。
稍后,数据发生更改,之后 rowCount() 再次返回 256 (3)。

所以看起来 fetchMore() 必须在每次对 sql 模型的写操作后调用。但不是将这个 while/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() 中获取: assert(!sql_model->canFetchMore())
这是因为 rowCount() 无法向我报告正确的行计数作为失败状态,因此断言。换句话说,我宁愿让我的应用程序崩溃而不是使用不正确的行数。

仅将其连接到 dataChanged() 信号(如 first answer 中所建议的: I would probably try to use dataChanged signal. )是不够的。我已将其连接到 dataChanged(const QModelIndex&, const QModelIndex&) , rowsInserted(const QModelIndex&, int, int) , rowsRemoved(const QModelIndex&, int, int)layoutChanged() .

似乎有效,断言还没有失败。

如果有人可以具体确认这一点(或解释为什么它并不总是有效),我将不胜感激。

最佳答案

你面临的困境和我最近遇到的类似。我写了一个 QT gui 程序,它做了以下事情——

一世。连接和查询 Oracle 数据库
ii.在 QTableView 中显示查询结果
三、将 QTableView 的结果导出到 .csv 文件
四、将 .csv 文件导入 loacl sqlite3 数据库
v. 连接并查询本地sqlite3数据库
六.执行查询并在另一个 QTableview 中显示结果

在步骤 ii.,(即将结果导出到 .csv)我观察到,虽然在 QTableView 上生成了 543 条记录,但只有 256 条记录被导出到 .csv 文件。

我在用,

int rows=model->rowCount();
int columns=model->columnCount();

for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
textData += model->data(model->index(i,j)).toString();
textData += ", "; // for .csv file format
}
textData += "\n"; // (optional: for new line segmentation)
}

QFile csvfile("/home/aj/ora_exported.csv");
if(csvfile.open(QIODevice::WriteOnly|QIODevice::Truncate))
{
QTextStream out(&csvfile);
out<<textData;
}
csvfile.close();

事实证明,该模型读取了 模型->行数在获取所有结果之前。

所以按照 SO 社区的建议,我使用了---
while (model->canFetchMore())
model->fetchMore();

int rows=model->rowCount();
int columns=model->columnCount();

for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
textData += model->data(model->index(i,j)).toString();
textData += ", "; // for .csv file format
}
textData += "\n"; // (optional: for new line segmentation)
}

并且所有记录都在 .csv 文件中填充(全部为 543)。

你可以引用我的问题 here .

关于qt - 何时或如何在 QSqlTableModel 上使用 fetchMore() 和 SQLite 数据库让 rowCount() 工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26369420/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com