anuj chauhan
anuj chauhan

Reputation: 173

How to create a TableView (Qt5.12) with model as ListModel that can host variable number of columns?

I am creating a Table with multiple rows and multiple columns. How can I use QML TableView to create a table with multiple rows and columns?

I tried with an older implementation of TableView but now want to create the same using the new TableView provided in Qt 5.12. Below is the example code of my older implementation

QtObject {
    id: internals
    property int rows: 0
    property int col: 0
    property int colwidth: 0
    property var columnName: []
}    
ListModel {
    id: libModel
}
TableView {
    id: tblview
    height: parent.height
    width: parent.width
    model: libModel

    style: TableViewStyle {
        itemDelegate: Rectangle {
            border.width: 1
            border.color: 'lightgrey'
            Text {
                id: textItem
                anchors.fill: parent
                text: styleData.value
            }
        }
    }

    resources: {
        var temp = []
        console.log("Column Count" + internals.col)
        for (var i = 0; i < internals.col; i++) 
            console.log("Creating a column")
            temp.push(columnComponent.createObject(tblview, {
                "role" : internals.columnName[i],
                "title" : internals.columnName[i]
            }))
        }
        return temp
    }
    Component {
        id: columnComponent
        TableViewColumn {
            width: internals.colwidth
        }
    }
}

Upvotes: 0

Views: 1384

Answers (1)

Mitch
Mitch

Reputation: 24416

I would recommend using a C++ model derived from QAbstractTableModel, as shown in the example.

For delegates, use DelegateChooser and DelegateChoice.

Unfortunately the documentation regarding TableView and DelegateChooser still needs to be improved:

Until that is added, I would recommend taking a look at the storagemodel manual test. Quoting the delegate code:

TableView {
    id: table
    anchors.fill: parent
    anchors.margins: 10
    clip: true
    model: StorageModel { }
    columnSpacing: 1
    rowSpacing: 1
    delegate: DelegateChooser {
        role: "type"
        DelegateChoice {
            roleValue: "Value"
            delegate: Rectangle {
                color: "tomato"
                implicitWidth: Math.max(100, label.implicitWidth + 8)
                implicitHeight: label.implicitHeight + 4

                Rectangle {
                    x: parent.width - width
                    width: value * parent.width / valueMax
                    height: parent.height
                    color: "white"
                }

                Text {
                    id: label
                    anchors.baseline: parent.bottom
                    anchors.baselineOffset: -4
                    anchors.left: parent.left
                    anchors.leftMargin: 4
                    text: valueDisplay + " of " + valueMaxDisplay + " " + heading
                }
            }
        }
        DelegateChoice {
            roleValue: "Flag"
            // We could use a checkbox here but that would be another component (e.g. from Controls)
            delegate: Rectangle {
                implicitWidth: checkBox.implicitWidth + 8
                implicitHeight: checkBox.implicitHeight + 4
                Text {
                    id: checkBox
                    anchors.baseline: parent.bottom
                    anchors.baselineOffset: -4
                    anchors.left: parent.left
                    anchors.leftMargin: 4
                    text: (checkState ? "☑ " : "☐ ") + heading
                }
            }
        }
        DelegateChoice {
            // roleValue: "String" // default delegate
            delegate: Rectangle {
                implicitWidth: stringLabel.implicitWidth + 8
                implicitHeight: stringLabel.implicitHeight + 4
                Text {
                    id: stringLabel
                    anchors.baseline: parent.bottom
                    anchors.baselineOffset: -4
                    anchors.left: parent.left
                    anchors.leftMargin: 4
                    text: display
                }
            }
        }
    }

Upvotes: 2

Related Questions