Qt模型视图,更新松散耦合模型和数据的视图

时间:2013-11-04 09:44:02

标签: qt model-view-controller model

这个问题是对以下两个问题的升级:

情况如下:

enter image description here

MODEL有一个指向SERVER的指针(SERVER代表Data),它通过它获取所需的数据并将它们格式化为QStrings,以便VIEW可以理解它们。该模型不保留QList的内部副本,它会直接访问它并将QTcpSocket *转换为QStrings方法中的QVariant QAbstractItemModel::data

但是,如果建立了与SERVER的新连接,那么套接字列表可以在没有模型或视图知道的情况下进行更改。在这种情况下,另一个QTcpSOcket *被附加到SERVER QList。

如何通知模型/数据更改的视图?

  • 在每个新连接上从SERVER调用QAbstractItemModel::reset()。我认为这很糟糕,因为它需要修改SERVER以满足MODEL的需要,在这种情况下我可以将MODEL和SERVER作为单个实体。

  • connect(&server, QTcpServer::newConnection, &model, &StationListModel::reset)尝试通过信号和插槽连接SERVER和MODEL。但是,&StationListModel::reset不是一个插槽,所以我认为这不是正确的方法。

我想知道在特定情况下哪些方法(如果有的话)被认为是合适的。而且坚持MODEL-SERVER松耦合是一个糟糕的设计选择吗?

3 个答案:

答案 0 :(得分:1)

以下是应该如何做的:

  1. 在SERVER中创建通知数据更改的信号(如果已足够,则使用现有的QTcpServer::newConnection信号)。
  2. 在模型类中创建一个或多个插槽,并将SERVER的信号连接到此插槽。
  3. 在插槽的实现中发出信号或调用内部方法(例如beginInsertRowsendInsertRows)或只是重置模型以通知视图有关新的更改。

答案 1 :(得分:0)

由于您需要以增量方式将新项目附加到视图中,我会按以下方式执行此操作:

在您的模型类中

// A slot
void MyModel::onNewConnection()
{
    // Append new socket to the list QList<QTcpSocket *>
    m_socketList.puch_back(new QTcpSocket);
    // Update the model.
    insertRow(0);
}

// Virtual function
bool MyModel::insertRows(int row, int count, const QModelIndex &parent)
{
    if (!parent.isValid()) {
        // We need to append a row to the bottom of the view.
        int rows = rowCount() - 1;

        beginInsertRows(parent, rows, rows);
        // Do nothing, but just inform view(s) that the internal data has changed
        // and these rows should be added.
        endInsertRows();
        return true;
    }
    return QAbstractItemModel::insertRows(row, count, parent);
}

代码中的某处

[..]
connect(&server, QTcpServer::newConnection, &model, &StationListModel::onNewConnection)

答案 2 :(得分:0)

我知道这是一个老问题,但我想分享我在处理完全相同的问题时所做的事情。 如果要将服务器指针放入模型实现中,并从QList< QTcpSocket *>获取所有模型信息,请使用此连接:

connect(server, SIGNAL(newConnection()), this, SIGNAL(modelReset()));