Search code examples
qmlrepeaterqt-quick

Using GridLayout with QAbstractModelList and Repeaters


I have following problem in QtQuick (QML). I want to display a table with data from QAbstractListModel in a table layout. I use GridlĹayout and repeaters for it:

  ScrollView {
        id: scrollView
        width: parent.width
        anchors.fill: parent
        clip: true
        ScrollBar.horizontal.policy: ScrollBar.AlwaysOn
        ScrollBar.vertical.policy: ScrollBar.AlwaysOn

        Repeater{
            model: _network.qqjourneyslist.length
            Item {
                GridLayout {
                    id: inr
                    columns: 5
                    width: rect2.width
                    layoutDirection: "RightToLeft"
                    anchors.left: parent.left
                    anchors.top: parent.bottom

                    Repeater{
                        model: _network.qqjourneyslist[index]
                        Item {
                            Text{
                                id:t1
                                //width: 100
                                text: model.startstop
                                //Layout.fillWidth: true

                            }
                            Text{
                                id:t2
                                //width: 100

                                text: model.starttime
                                //Layout.fillWidth: true
                                //anchors.left: t1.right
                            }
                            Text{
                                id:t3
                                //width: 100
                                text: model.lineno
                                //Layout.fillWidth: true
                                //anchors.left: t2.right
                            }
                            Text{
                                id: t4
                                //width: 100
                                text: model.endstop
                                // Layout.fillWidth: true
                                //anchors.left: t3.right
                            }
                            Text{
                                id: t5
                                //width: 100
                                text: model.endtime
                                //Layout.fillWidth: true
                                //anchors.left: t4.right
                            }
                        }
                    }
                }
            }
        }
    }

The problem is, that when I insert a repeater in the GridLayout the flow is destroyed and the Texts are overwriting each other. I tried a lot of things like insert width for the texts or use Layout.row, Layout.columns, but nothing works.
I also looked at Populate GridLayout with Repeater but this topic did not help in my case or at least I did not find a way how to modify it for my purpose. _network.qqjourneislist is a QList wiht QAbstractListModel which I would like to use and outside of the Layout there are working fine. Could you please help me how to use a repeater and QAbstractListModel?
I do not keen on using GridLayout I just want to create a table with row and columns for my model. I know there are lot of another table objects but I do not know which to use and trying all out is a long way for me.
I am glad of every advice I receive and thank you for it!

EDIT....

The solution with ColumnLayout and RowLayout is working until I use a Repeater in a Repeater which yields to that the text lines are not produced.

The code is following:

 ColumnLayout {
            id: inr
           // anchors.fill: parent
            width: parent.width
            layoutDirection: "LeftToRight"
            anchors.left: parent.left
            anchors.margins: 15
            //anchors.horizontalCenter: parent
            anchors.top: parent.top
            anchors.right: parent.right
    Repeater{
        model: _network.qqjourneyslist.length

   Repeater{
       id: rep1
        model: _network.qqjourneyslist[index]
            //width: inr.width
            //height: 50
            RowLayout{
                height: 20
                Layout.preferredHeight: 20
                spacing: 10
                    Text{
                        id:t1
                        width: wind.implicitWidth/3
                        //anchors.left: parent.left
                        //anchors.top: parent.top
                    text: model.startstop
                    font.pointSize: 12
                    Layout.preferredWidth: wind.implicitWidth/3

                    }

            Text{
                id:t2
                //width: 100

            text: model.starttime
            font.pointSize: 12
            font.bold: true
            //Layout.fillWidth: true
            //anchors.left: t1.right
            }
            Text{
                id:t3
                //width: 100
            text: model.lineno
            font.pointSize: 12
            color: "red"
            //Layout.alignment: Qt.AlignVCenter
            horizontalAlignment: Text.AlignHCenter
            //Layout.preferredWidth: parent.implicitWidth/3
            Layout.fillWidth: true
            }
            Text{
                x:wind.implicitWidth/12*9
                id: t4

            text: model.endstop
            Layout.alignment: Qt.AlignLeft
            font.pointSize: 12
            Layout.preferredWidth: parent.implicitWidth/3
            //anchors.left: t3.right
            }
            Text{
                id: t5
                //width: 100
            text: model.endtime
            Layout.alignment: Qt.AlignRight
            font.pointSize: 12
            font.bold: true
            //Layout.fillWidth: true
            //anchors.left: t4.right
            }
            }

            }
   RowLayout{
       height: 12
       //Layout.preferredHeight: 12
       //anchors.top: rep1.bottom
       Rectangle{
           //width: parent.width
           //Layout.
           Layout.row: 3*index
           Layout.preferredHeight: 12
           Layout.fillWidth: true
           color: "grey"
           //Layout.alignment: Qt.AlignLeft
           //Layout.fillWidth: parent
           //Layout.alignment: Qt.Right
           radius: 5
       }
        }}}

I want to produce something like that (the lower rectangle)

right version

but I get only the rectangles and no text. If I remove the last RowLayout then the texrows are displayed properly.

something is wrong

The _network.qqjournieslist is a QList of QObejcts* - QAbstractListModel - so it should be possible to assign it to model. Thanks for every help!


Solution

  • The Text objects overwrite themselves because their parent is an Item, which doesn't tell them where to be positioned. You don't really describe how you want the output to look, so I'll make an assumption that you want those 5 text strings to appear as a single row in your grid. Then you can just use a Column with a Row, (or a ColumnLayout with a RowLayout if you prefer).

    Column {
        Row {
            Repeater {
                model: _network.qqjourneyslist
                Text {
                    width: 100 // Column 1 width
                    text: model.startstop
                }
                Text {
                    width: 100 // Column 2 width
                    text: model.starttime
                }
                ...
            }
        }
    }
    

    EDIT:

    Your updated code doesn't work because you seem to misunderstand how Repeaters work. The model of a Repeater can either be a count of how many times it should repeat, or a list of some sort that tells the Repeater how many items to create.

    Your first Repeater uses the length of your list as a model, which is ok. Let's say its value is 10. That means it will create 10 of whatever is inside it. And what's inside that Repeater? Another Repeater. The model of that second Repeater though is the contents of a single item in your list. That's a problem. Unless that item is also a list of some sort, the Repeater won't know how to use it as a count. That's why in my code above, I changed your example to only use a single Repeater. That's all that's needed for your case. The model for each row needs to be repeated, but not your columns.