【问题标题】:Qt Model View, update view on loosely coupled Model and DataQt 模型视图,更新松耦合模型和数据的视图
【发布时间】:2013-11-04 09:44:01
【问题描述】:
本题是对以下两题的升级:
情况如下:
MODEL 有一个指向 SERVER 的指针(SERVER 代表Data),通过它获取所需的数据并将它们格式化为QStrings,以便VIEW 可以理解它们。该模型不保留QList 的内部副本,它直接访问它并在QVariant QAbstractItemModel::data 方法中将请求QTcpSocket * 转换为QStrings。
但是,如果建立了与 SERVER 的新连接,则套接字列表可能会在模型或视图不知道的情况下发生变化。在这种情况下,另一个 QTcpSOcket * 将附加到 SERVERs QList。
如何通知视图模型/数据发生变化?
在每个新连接上从服务器调用QAbstractItemModel::reset()。我认为这很糟糕,因为它需要根据模型的需要修改服务器,在这种情况下,我可以将模型和服务器作为一个实体。
connect(&server, QTcpServer::newConnection, &model, &StationListModel::reset) 尝试通过 Signals 和 Slots 连接 SERVER 和 MODEL。但是,&StationListModel::reset 不是空位,所以我认为这不是正确的方法。
我想知道在给定的情况下,哪些方法(如果有的话)被认为是合适的。坚持 MODEL-SERVER 松耦合是一个糟糕的设计选择吗?
【问题讨论】:
标签:
qt
model-view-controller
model
【解决方案1】:
这是应该怎么做的:
- 在 SERVER 中创建信号以通知数据更改(或使用现有的
QTcpServer::newConnection 信号,如果足够的话)。
- 在您的模型类中创建一个(或多个)槽,并将 SERVER 的信号连接到该槽。
- 在插槽的实现中发出信号或调用内部方法(例如
beginInsertRows、endInsertRows)或只是重置模型以通知视图有关新的更改。
【解决方案2】:
由于您需要逐步将新项目附加到您的视图中,因此我将通过以下方式执行此操作:
在你的模型类中
// 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)
【解决方案3】:
我知道这是一个老问题,但我想分享一下我在处理完全相同的问题时所做的事情。
如果您将服务器指针放入模型实现中,并且您从 QList< QTcpSocket *> 获取所有模型信息,请使用此连接:
connect(server, SIGNAL(newConnection()), this, SIGNAL(modelReset()));