Search code examples
c++qtqmltableview

QML TableView: How do you only display a subset of model index data?


I want to display a subset of columns from an large existing C++ TableModel in a new QML TableView.

All the documenation and examples I've read override QAbstractItemModel::roleNames() to expose model data associated with the roles as properties in QML.

The problem is that the legacy TableModel's data() function has a complex implementation tightly coupled to Qt::DisplayRole:

\\...
QVariant LegacyModel::data(const QModelIndex& index, int role) {
    switch(role) {
    \\...
    case Qt::DisplayRole:
        switch(LegacyTableColumn.at(index.column())) {
            \\ lots of stuff
        }    
    }
    \\...
}
\\...

As such, I'd prefer to avoid overriding QAbstractItemModel::roleNames() as it will mean substantial refactoring of the above data() function.

I have a QML view showing all the columns in each model row:

TableView {
    anchors.fill: parent

    model: LegacyModel

    delegate: RowLayout {
        implicitWidth: parent.width

        Text {
            text: model.display // i.e., inferred from Qt::DisplayRole
                                // can I access column data here somehow?
        }
    } 
} 

But I only want to display a small set of columns.

Is there a way to do that without overriding roleNames() and using those as properties in the view?


Solution

  • As far as I can tell it looks like the only way to avoid custom roles is to hack a Q_INVOKABLE function in the model:

    // LegacyModel.h:
    ...
    Q_INVOKABLE QVariant getMyData(int row, int column) const { return m_data[row][column]; }
    ...
    
    // TableView.qml:
    
    TableView {
        ...
        model: LegacyModel
    
        delegate: RowLayout {
            ...
            Text {
                text: model.getMyData(row, 2) 
                                    
            }
            Text {
                text: model.getMyData(row, 5) 
                                    
            }
            // etc.
        } 
    } 
    

    Not a great solution, so I'm going to create a new model with custom roles insted.

    Related:

    How to implement QML ListModel like get method for an QAbstractListModel derived model

    How to access ListView's current item from qml

    How to access Items stored in a QAbstractListmodel in QML(by delegates) otherwise than using item roles?

    QML Model data by index