The Qt model classes are optimized for situations where small changes are made to existing data. In some situations new data is only available as an updated list of all items possible with additions, deletions and moves. This utility class aims to make implementing a read-only model easier in such a situation. If the items have a stable identifier such as a file path, an database id or similar this class can automatically translate a new state with a full list into the changes the model system expects. This class is intended for small to medium sized models.

As example the following code creates a model based on a filesystem directory assuming file name are stable identifiers in this case.

An instance is created with the type of the identifier/key to use and how many columns the model should have:

Tui::Misc::AbstractTableModelTrackBy<QString> model{2};

It can then be updated as data comes in and changes:

QList<QFileInfo> files = QDir().entryInfoList(QDir::NoFilter, QDir::Name);
QVector<Tui::Misc::AbstractTableModelTrackBy<QString>::Row> newData;
for (const auto &file: files) {
    Tui::Misc::AbstractTableModelTrackBy<QString>::Row row;
    row.key = file.absoluteFilePath();
    QMap<int, QVariant> column1;
    column1[Qt::DisplayRole] = file.fileName();

    QMap<int, QVariant> column2;
    column2[Qt::DisplayRole] = file.lastModified();


Here files is the data to update the model to. The code transforms the data into a QVector of Tui::Misc::AbstractTableModelTrackBy::Row instances.

In each row the Tui::Misc::AbstractTableModelTrackBy::Row::key is set to the stable identifier of the row. The key is how row removal, addition and reordering is detected. Tui::Misc::AbstractTableModelTrackBy::Row::columns is a QVector that stores the assocation of Qt item roles to their data for each column.

Finally setData updates the model.

template<typename KEY>
class Tui::Misc::AbstractTableModelTrackBy : public QAbstractTableModel

Utility class to implement a QAbstractTableModel based on a list of rows with stable identifier.


struct Row

A row of data for use in setData.

KEY key

The key to be used for row removal, addition and reordering detection.

If a row is the “same” row as in a previous update it must have the same value for key.

QVector<QMap<int, QVariant>> columns

A list of columns for this row.

Each item is a mapping from Qt item roles to their data.


AbstractTableModelTrackBy(int columns)

Creates an empty model with the number of columns set to columns.


void setData(const QVector<Tui::Misc::AbstractTableModelTrackBy::Row> &data)

Updates the model using the new data from data.

Model events for row removal, addition and movements are generated as well as model events for data that has changed relative to the previous state in each table cell.