我想将QSqlQueryModel发送到另一个具有QDatastream和QTcpSocket的客户端。我希望删除一些行,并向QSqlQueryModel中添加少量额外行(而不更改数据库),并像以下伪代码那样将其发送给客户端:-
QTcpSocket socket;
socket.setSocketDescriptor(handle);
socket.waitForReadyRead(WAIT_TIME);
QByteArray req = socket->readAll();
QDataStream reqstream(&req,QIODevice::ReadOnly);
QSqlQueryModel MyModel;
....
// fetch data with MyModel
// add/remove some rows from that model without adding/removing them from actual database
....
QByteArray res;
QDataStream resstream(&res,QIODevice::WriteOnly);
resstrem << MyModel;
socket.write(res);我怎样才能实现这个,而不需要创建模型的新的深拷贝。在客户端,它应该只接收带有数据的模型,这样我就可以在QML中显示它。
发布于 2020-02-11 11:48:24
QAbstractItemModel的任何子代的目的都是采用一些数据来表示视图(小部件)。
所以基本上,你在尝试做一些在这个类的设计之外的事情。就像用铲子打钉子一样。这是可能的,但很危险,不被推荐。
只需使用QSqlQuery (使用锤子)读取底层数据,迭代行、读取列并以某种序列化格式存储它们。您可以使用QDataStream:
QDataStream out{&socket};
QSqlQuery query{"SELECT country FROM artist"};
while (query.next()) {
out << query.value(0).toString();
}这是可以使这个异步的。
发布于 2020-02-10 23:14:56
如果不创建一个“深度副本”,您就不能在Qt中做您想做的事情,也不能做任何其他事情。
如果您使用的是真实的数据库,而不是SQLite或其他不使用数据库引擎的低端存储方法,那么您可以不执行传输就可以做您想做的事情。阅读您所选择的数据库的临时表。您可以选择成一个临时表。这样做的效率要高得多,因为具有活动引擎的数据库只会创建指针游标,但将其视为真正的表。如果产生的游标对于RAM来说太大,它会将其写入某个临时划痕区域。
然后,让客户端告诉服务器应用程序删除要从临时表中删除的行,并插入要添加的行。只需确保您的服务器从那时起就可以在临时表上操作。
注意:如果您使用的是一个非常糟糕的电子表格示例,该示例将数据结果绑定到GUI线程中的电子表格,则无法修复该问题。我在网上发现的每一个官方例子都很糟糕。永远不要在主事件循环中执行数据库I/O。
您可能也希望获得这本书的副本。它将不包含这个问题的答案,但它确实包含了许多可用的数据库示例。
https://stackoverflow.com/questions/60089046
复制相似问题