0

我想用 QDatastream 和 QTcpSocket 将 QSqlQueryModel 发送到另一个客户端。我想删除一些行并向 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 中显示它。

4

2 回答 2

1

如果不创建“深拷贝”,您将无法在 Qt 中做任何您想做的事情,或者其他任何事情。

如果您使用的是真正的数据库,而不是 SQLite 或其他不使用数据库引擎的低端存储方法,您可以在不进行传输的情况下做您想做的事情。阅读您选择的数据库的临时表。您可以SELECT INTO临时表。这更有效,因为具有活动引擎的数据库只会创建指针游标,但会将其视为真实表。如果生成的光标对于 RAM 来说太大,它会将其写入某个临时暂存区。

之后,只需让您的客户端告诉服务器应用程序 DROP 您要从临时表中删除的行并 INSERT 您要添加的行。只需确定您的服务器从那时起就在临时表上运行。

注意:如果您正在使用一个非常糟糕的电子表格示例,该示例将数据结果从 GUI 线程内绑定到电子表格,您将无法解决这个问题。我在网上找到的每个官方示例都非常糟糕。永远不要在主事件循环中进行数据库 I/O。

您可能还想获得这本书的副本。它不会包含这个问题的答案,但它确实包含许多工作数据库示例。

于 2020-02-10T23:14:56.940 回答
1

QAbstractItemModel的任何后代的目的是将一些数据用于可以呈现它们的视图(小部件)。

所以基本上你正在尝试做一些超出这个类设计的事情。这就像试图用铁锹敲钉子一样。这是可能的,但很危险,不推荐。

只需使用QSqlQuery(使用锤子)迭代读取列的行并以某种序列化格式存储它们来读取降基数据。您可以QDataStream为此使用:

    QDataStream out{&socket};

    QSqlQuery query{"SELECT country FROM artist"};
    while (query.next()) {
        out << query.value(0).toString();
    }

可以使这个异步。

于 2020-02-11T11:48:24.820 回答