Search code examples
qtqmlqtquick2qt-quick

QML: How to set coordinates inside Repeater


I have an issue with setting coordinates inside Repeater:

import QtQuick

Window {
   id: mainWindow
   property int wi: 640
   property int he: 500
   width: wi
   height: he
   visible: true
   title: qsTr("Game")

Rectangle {
    id: gameWindow
    width: wi/1.6
    height: he
    anchors.right: parent.right
    visible: true
    color: "black"
    clip: true

    Grid {
        id: gameGrid
        columns: 25
        spacing: 0
        rows: 32
        anchors.fill: parent

        Repeater {
            model: 600

            Rectangle {
                width: wi/40
                height: 20
                border.width: 2
                color: "grey"
            }
        }
    }

    Grid {
        id: sGrid
        columns: gameGrid.columns
        spacing: gameGrid.spacing
        rows: gameGrid.rows
        anchors.fill: gameGrid

        Repeater {
            model: 5
           
            Rectangle {

            //                 anchors.horizontalCenter: sGrid.horizontalCenter
            //                 anchors.verticalCenter: sGrid.verticalCenter
            //                 x: (wi/2) + (index * (wi/40) )
            //                 y: he/2
               width: wi/40
               height: 20
               border.width: 1
               color: "red"
            }
        }
       }
      }
     }

Whole code above, but my question is about the second Repeater with 5 Rectangles. I have tried to solve that with many ways. Most obvious seemed to me placing coordinates inside Repeater, but now I know it does not work like this - I have to place coordinates somehow inside Rectangle. I have commented code, where are the ways I have tried to solve this.

Anchors work very well - it places the first element exactly where I am expecting. Problem appears with the next elements. They are placing inside the same element of Grid. I do not understand why the coordinates does not working. Documentation shows I could use "index", don't know, maybe the point is that's "read only" property? I have tried to set Rectangle with prefix "delegate:" with the same result as well.


Solution

  • In your question, you mention you have Grid + Repeater + Rectangle. I am not sure what you want to achieve, but, it feels like you may have better luck by going GridView + Rectangle because GridView supports a model.

    Since you want coordinate control of your Rectangles, it is possible to do this alone with Repeater + Rectangle. No need for Grid since the Grid will impact the coordinate system of your Rectangle.

    Below illustrates how you can use a simple ListModel to control the placement of your Rectangles:

    import QtQuick
    import QtQuick.Controls
    Page {
        Repeater {
            model: ListModel {
                ListElement { p:100; q:100; w:50; h:50; c:"red"; o:0 }
                ListElement { p:200; q:100; w:50; h:50; c:"green"; o:15 }
                ListElement { p:300; q:200; w:50; h:50; c:"blue"; o:30 }
                ListElement { p:300; q:300; w:50; h:50; c:"orange"; o:45 }
                ListElement { p:200; q:400; w:50; h:50; c:"purple"; o:60 }
            }
            delegate: Rectangle {
                x: p
                y: q
                width: w
                height: h
                color: c
                rotation: o
            }
        }
    }
    

    You can Try it Online!

    [EDIT]

    With the following, it shows how you could use index in 10 delegates to place your rectangles using a formula:

    import QtQuick
    import QtQuick.Controls
    Page {
        Repeater {
            model: 10
            delegate: Rectangle {
                x: 100 + (index % 4) * 100
                y: 100 + Math.floor(index / 4) * 100
                width: 50
                height: 50
                color: ["green","red","orange","blue","purple"][index%5]
                rotation: index * 10
                Text {
                    anchors.centerIn: parent
                    text: index
                    color: "white"
                }
            }
        }
    }
    

    You can Try it Online!