1

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?

jusko
  • 76
  • 8
  • please provide a [mre] – eyllanesc Jan 09 '21 at 14:54
  • it's a conceptual question, not a reproducible problem. is their something specifically unclear about it? – jusko Jan 09 '21 at 15:52
  • No, it is not only conceptual since you indicate: *But I only want to display a small set of columns.* so you have a code that has an error since the role "display" should cover what you want but it seems that your model is very peculiar – eyllanesc Jan 09 '21 at 16:00
  • It's hard to simplify the model as that `data()` function is ~300 lines of legacy code. To clarify more: `model.display` displays the whole _row_ of data. Is their a way to display a single column (i.e., something like `model.display[2]` etc.) without resorting to custom roles? – jusko Jan 09 '21 at 16:24

1 Answers1

0

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

jusko
  • 76
  • 8