Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Strange behaviour when accessing ListModel outside of delegate



  • Hello everybody,
    I hope someone can explain the following behavior of ListView and ListModel.

    I am new to programming Qt and especially QML / Qt Quick. I am currently experimenting with the existing elements to learn the concepts of QML.
    I tried to use the ListView component to create a table-like view. It seems that showing a simple table is a bit more complex than I thought. I am still testing the different views. I know that there is also a TableView in Controls 1 as well as a newer development. However, these do not really appeal to me yet.

    Here is my code that works, but I don't know why.

    // CustomTableView.qml
    
    import QtQuick 2.14
    import QtQuick.Controls 2.14
    
    Item {
        ListModel {
            id: headerModel
    
            Component.onCompleted: {
                headerModel.append(
                {
                    columns: [
                        {
                            "value": "Column 1",
                            "width": 35,
                            "alignment": Text.AlignLeft
                        },
                        {
                            "value": "Column 2",
                            "width": 140,
                            "alignment": Text.AlignRight
                        },
                        {
                            "value": "Column 3",
                            "width": 140,
                            "alignment": Text.AlignRight
                        },
                        {
                            "value": "Column 4",
                            "width": 35,
                            "alignment": Text.AlignLeft
                        },
                        {
                            "value": "Column 5",
                            "width": 170,
                            "alignment": Text.AlignRight
                        }
                    ]
                })
            }
    
        ListModel {
            id: dataModel
    
            Component.onCompleted: {
                dataModel.append([
                    {
                        columns: [
                             {"value": "X"},
                             {"value": (Math.round(Math.random()*10e6)/10e3).toString()},
                             {"value": (Math.round(Math.random()*10e6)/10e3).toString()},
                             {"value": "v<sub>X</sub>"},
                             {"value": (Math.round(Math.random()*10e6)/10e3).toString()}
                        ]
                    },
                    {
                        columns: [
                             {"value": "Y"},
                             {"value": (Math.round(Math.random()*10e6)/10e3).toString()},
                             {"value": (Math.round(Math.random()*10e6)/10e3).toString()},
                             {"value": "v<sub>Y</sub>"},
                             {"value": (Math.round(Math.random()*10e6)/10e3).toString()}
                        ]
                    }
                ])
            }
        }
    
        }
    
        ListView {
            id: tableView
    
            anchors.fill: parent
    
            clip: true
    
            property int rowSpacing: 10
            property int columnSpacing: 10
    
            model: dataModel
    
            header: Row {
                spacing: tableView.columnSpacing
                Repeater {
                    // actually I wan't to access the model in this way to save me one repeater loop.
                    // model: headerModel.get(0).columns
                    // but nowhere else as in the delegate I can access the columns role
                    // concole output: qrc:/CustomTableView.qml:85: TypeError: Cannot read property 'columns' of undefined
                    model: headerModel
                    Repeater {
                        model: columns
                        Text {
                            text: model.value
                            width: model.width
                        }
                    }
                }
            }
    
            delegate: Row {
                spacing: tableView.columnSpacing
                Repeater {
                    model: columns
                    Text {
                        text: value
                        width: headerModel.get(0).columns.get(index).width // this line works only at this position but why can I access columns here and not somewhere else?
                    }
                }
            }
    
            ScrollIndicator.horizontal: ScrollIndicator { }
            ScrollIndicator.vertical: ScrollIndicator { }
        }
    
    
    
    }
    
    
    

    I did some comments in the code above to illustrate my problem.
    Additionally it seems that the headerModel will be instantiate later then the dataModel? Is there a rule in which order elements will instantiate?

    Thanks for helping.

    Best regards.



  • Can nobody give me a hint?

    What are other suitable ways to create a responsible table?


Log in to reply