ModelViews

Several classes act as model views or something similar. An example for a true model view is FlarmMapWidget which is a view for FlarmList and GpsTracker. An example that is not strictly a model view but uses similar techniques is GpsTracker which uses an NmeaDecoder.

This page describes the techniques employed by these clases.

General

The model may be NULL. Make sure that all methods accessing the model handle this case correctly.

An alternative technique, used by Qt's own model views, is to use a (static) null object.

Setting the model

The model is set by a method called setModel or something more specific (especially for classes using several models) like setGpsTracker.

This method performes the following steps:

Check if the new model is the same as the current model:

if (model==this->model)
    return;

Disconnect the signals of the old model, if there is an old model:

if (this->model)
{
    // Disconnect all signals of the model from this view
    _sourceModel->disconnect (this);

    // Alternatively, you can disconnect the signals individually:
    disconnect (this->model, SIGNAL (dataChanged (QModelIndex, QModelIndex)),
                this       , SLOT   (dataChanged (QModelIndex, QModelIndex)));
    // ...
    disconnect (this->model, SIGNAL (destroyed()),
                this       , SLOT   (modelDestroyed ()));
}

Store the the new model:

this->model=model;

If the new model is valid (it may be NULL), connect its signals. Pay particular attention to the destroyed() signal:

if (this->model)
{
    connect (this->model, SIGNAL (dataChanged (QModelIndex, QModelIndex)),
             this       , SLOT   (dataChanged (QModelIndex, QModelIndex)));
    // ...
    connect (this->model, SIGNAL (destroyed()),
             this       , SLOT   (modelDestroyed ()));
}

You may have to reset internal data and/or refresh the view. You can probably use the same methods called on model reset for this.

In a proxy model, the process of resetting internal data must be wrapped in calls to beginResetModel () and endResetModel (). You can probably use the methods connected to the source model's signals with the same names.

Reacting to model deletion

In the slot connected to the model's destroyed() signal, set the current model to NULL:

this->model=NULL;

Do not call setModel (NULL) - this will try to disconnect the signals which are no longer valid at this point.

You will probably want to refresh the view after that; if the model is a QAbstractItemModel, you can probably use the method connected to the model's modelReset slot.


Related

Wiki: Home