TheMeaningfulEngineer
TheMeaningfulEngineer

Reputation: 16329

Qt Model View, update view on loosely coupled Model and Data

This question is an upgrade on the following two questions:

Here is the situation:

enter image description here

MODEL has a pointer to the SERVER (SERVER represents Data) through which it gets the required data and formats them into QStrings, so that the VIEW can understand them. The model keeps no internal copies of the QList, it accesses it directly and converts the requ QTcpSocket * to QStrings in the QVariant QAbstractItemModel::data method.

However the list of sockets can change without the Model or View knowing about it if a new connection to the SERVER is established. In that case another QTcpSOcket * is appended to the SERVERs QList.

How to notify the View on the Model/Data change?

I would like to hear which of the mentioned approaches (if any) is considered appropriate in the given situation. And is the insisting on MODEL-SERVER loose coupling a bad design choice?

Upvotes: 0

Views: 526

Answers (3)

albertTaberner
albertTaberner

Reputation: 2149

I know this is an old question, but I would like to share what I do when I was working on the exactly same issue. If you are placing the server pointer into the model implementation and you get all the model information from the QList< QTcpSocket *> use this connection:

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

Upvotes: 0

vahancho
vahancho

Reputation: 21220

Since you need to incrementally append new items to your view, I would do this in the following way:

In your model class

// 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);
}

Somewhere in your code

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

Upvotes: 0

Pavel Strakhov
Pavel Strakhov

Reputation: 40492

Here is how it should be done:

  1. Create signals in SERVER that notify about data change (or use existing QTcpServer::newConnection signal if it is sufficient).
  2. Create a slot (or slots) in your model class and connect SERVER's signal to this slot.
  3. In the slot's implementation emit signals or call internal methods (e.g. beginInsertRows, endInsertRows) or just reset the model to notify the view about new changes.

Upvotes: 1

Related Questions