10
votes

I am creating a Table using the new qml tableview (Qt 5.12). I am able to create a model in C++ and able to populate the model in tabular format along with scrollbar.How do I add column headers to this table? Code:

import QtQuick 2.12
import QtQuick.Controls 2.5
import Qt.labs.qmlmodels 1.0
//import QtQuick.Controls.Styles 1.4
import TableModel 0.1
Rectangle {
    id:table
    border.width: 3
    border.color: 'dark blue'
    QtObject{
        id:internals
        property int rows:0
        property int col:0
        property int colwidth:0
        property var columnName:[]
    }

    function setRows(num){ internals.rows = num}
    function setCols(num){ internals.col =  num}
    function setColWidth(num){internals.colwidth = num}

    function setColNames(stringlist){
        if(stringlist.length > 1)
            internals.col = stringlist.length

    dataModel.setColumnName(stringlist);
    }

    function addRowData(stringlist){
        var len = stringlist.length

         if(len >0)
         {
             dataModel.addData(stringlist)
         }
    }

    TableModel {
        id:dataModel
    }

    TableView{
            id:tbl
            anchors.top: headerCell
            anchors.fill: parent
            //columnSpacing: 1
            //rowSpacing: 1
            clip: true

           ScrollBar.horizontal: ScrollBar{}
           ScrollBar.vertical: ScrollBar{}

            model:dataModel

            Component{
                id:datacell
                Rectangle {
                    implicitWidth: 100
                    implicitHeight: 20
                    color: 'white'
                    border.width: 1
                    border.color: 'dark grey'
                    Text {
                        id:txtbox
                        anchors.fill: parent
                        wrapMode:                           Text.NoWrap
                        clip:                               true
                        verticalAlignment:                  Text.AlignVCenter
                        horizontalAlignment:                Text.AlignHCenter
                        text: display
                    }
                }
            }

        }

        function init(){
            console.log("Calling init")
            tbl.delegate= datacell
        }

}
3
As said in the Qt docs: You provide title and size of a column header by adding a TableViewColumn so you just have to add one or more TableViewColumn itemsfolibis
@folibis that's the old TableView, OP is using the new one.Mitch
Ah, ok, didn't paid attention. What about to implementing headerData in the model?folibis

3 Answers

13
votes

Currently TableView does not have headers so you should create it, in this case use Row, Column and Repeater.

On the other hand you must implement the headerData method and you must do it Q_INVOKABLE.

class TableModel : public QAbstractTableModel
{
    Q_OBJECT

public:
    // ...
    Q_INVOKABLE QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
    // ...
TableView {
    id: tableView
    model: table_model
    // ...
    Row {
        id: columnsHeader
        y: tableView.contentY
        z: 2
        Repeater {
            model: tableView.columns > 0 ? tableView.columns : 1
            Label {
                width: tableView.columnWidthProvider(modelData)
                height: 35
                text: table_model.headerData(modelData, Qt.Horizontal)
                color: '#aaaaaa'
                font.pixelSize: 15
                padding: 10
                verticalAlignment: Text.AlignVCenter

                background: Rectangle { color: "#333333" }
            }
        }
    }
    Column {
        id: rowsHeader
        x: tableView.contentX
        z: 2
        Repeater {
            model: tableView.rows > 0 ? tableView.rows : 1
            Label {
                width: 60
                height: tableView.rowHeightProvider(modelData)
                text: table_model.headerData(modelData, Qt.Vertical)
                color: '#aaaaaa'
                font.pixelSize: 15
                padding: 10
                verticalAlignment: Text.AlignVCenter

                background: Rectangle { color: "#333333" }
            }
        }
    }

enter image description here

The complete example you find here.

4
votes

If you're using Qt 5.15, you can use a HorizontalHeaderView for column labels.

https://doc.qt.io/qt-5/qml-qtquick-controls2-horizontalheaderview.html

There's also VerticalHeaderView for row labeling.

https://doc.qt.io/qt-5/qml-qtquick-controls2-verticalheaderview.html

2
votes

I'm new to the QML. I came to the answer of eyllanesc so many times through my struggle with the new TableView (qt 5.12+), so I wanna thank you and share what helped me even more. It's this video: Shawn Rutledge - TableView and DelegateChooser: new in Qt 5.12 part of Qt Virtual Tech Summit 2019

The discussed code

It's a bit long but he covers

  • the differences between old and new TableView

  • how to create universal model for the views

  • resizable headers

  • different representation per column type - DelegateChooser

  • sortable columns

  • column reorder