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

How to centralize items/rectangles/... inside a grid?



  • Hello!

    I'm trying to understand how I can centralize some rectangles dynamically inserted in this way:

    • Rect1 inserted
        [Rect 1]     
    
    • Rect2 inserted
    [Rect1]  [Rect2]
    
    • Rect 3 inserted
    [Rect1]  [Rect2]
        [Rect 3]
    
    Grid {
               id: sampleGrid
               spacing: 20
               columns: 2
    
               anchors {
                   top: parent.top
                   topMargin: 400
                   horizontalCenter: parent.horizontalCenter
               }
    
              horizontalItemAlignment: Grid.AlignHCenter // didn't work
              verticalItemAlignment: Grid.AlignVCenter   // didn't work
    
               // Block 1
               Rectangle {
                   id: blk1
                   color: "blue"
                   width: 200
               }
    
               // Block 2
               Rectangle {
                   id: blk2
                   color: "red"
                   width: 200
               }
    
               // Block 3
               Rectangle {
                   id: blk3
                   color: "blue"
                   width: 200
               }
    }
    

    I tried grid and float positioners, but there is no way to centralize objects inside them. Or is there?

    Could someone help me?

    Thanks a lot!



  • I didn't find any clever way to solve this.
    In my project, I just need 3 rectangles so I used a script to align these items. I know this is an ugly solution, but I will be glad if someone shows a good one. :)

    Solution:
    First I replaced grid to row and build a script to centralize the visible items.

    countVisibleItems = ...
    if(countVisibleItems === 3) {
               rowSample.anchors.topMargin = 225
    
               rowSample.children[0].anchors.left = rowSample.left
               rowSample.children[0].anchors.leftMargin = 60
    
               rowSample.children[1].anchors.left = rowSample.children[0].right
               rowSample.children[1].anchors.leftMargin = 10
    
               rowSample.children[2].anchors.top = rowSample.children[1].bottom
               rowSample.children[2].anchors.topMargin = 10
               rowSample.children[2].anchors.left = rowSample.left
               rowSample.children[2].anchors.leftMargin = 220
    }
    else if(countVisibleItems === 2) {
               var v = 0
               var previousElem = 0
               for(i=0; i<3; i++) {
                   if (rowSample.children[i].visible) {
                       if(v === 0) {
                           rowSample.children[i].anchors.left = rowSample.left
                           rowSample.children[i].anchors.leftMargin = 60
                           v++
                           previousElem = i
                       }
                       else {
                           rowSample.children[i].anchors.left = rowSample.children[previousElem].right
                           rowSample.children[i].anchors.leftMargin = 10
                       }
                   }
               }
    }
    else if(countVisibleItems === 1) {
               for(i=0; i<3; i++) {
                   if (rowSample.children[i].visible) {
                       rowSample.children[i].anchors.left = rowSample.left
                       rowSample.children[i].anchors.leftMargin = 220
                   }
               }
    }
    


  • hi,
    @carpajr said in How to centralize items/rectangles/... inside a grid?:

    In my project, I just need 3 rectangles

    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        property int visibleCount : 1
        property int _spacing : 2
    
        NumberAnimation on visibleCount {
            duration: 3000
            loops: Animation.Infinite
            from: 1
            to:3
            running: true
        }
        Rectangle{ 
            id: sampleRec
            color: "#9c9c9c"
            width: 400
            height: 400
            anchors {
                top: parent.top
                horizontalCenter: parent.horizontalCenter
            }
    
            Rectangle{
                id:r1
                height: parent.height/2
                width: parent.width/2
                color: "#2d2d2d"
                anchors.left: parent.left
                anchors.leftMargin: visibleCount>1? 0 : width/2
    
               Behavior on anchors.leftMargin{
                NumberAnimation{duration: 500}
               }
            }
            Rectangle{
                id:r2
                anchors.verticalCenter: r1.verticalCenter
                height: parent.height/2
                width: parent.width/2
                anchors.left: r1.right
                anchors.leftMargin:  _spacing
                color: "#2d2d2d"
               visible: visibleCount>=2
    
            }
            Rectangle{
                id:r3
                anchors.top: r1.bottom
                anchors.topMargin: _spacing
                anchors.horizontalCenter:  parent.horizontalCenter
                height: parent.height/2
                width: parent.width/2
                color: "#2d2d2d"
                visible: visibleCount>=3
            }
        }
    }
    


  • @LeLev,

    Thank you for your suggestion. It's an interesting approach. :)

    I would like to know whether there is a positioner structure that could handle this automatically. A grid/gridview with this feature would be spectacular!



  • @carpajr said in How to centralize items/rectangles/... inside a grid?:

    I would like to know whether there is a positioner structure that could handle this automatically. A grid/gridview with this feature would be spectacular!

    You could to use a simple ternary condional to aplly a horizontal align in last item if has an odd number of elements.

    anchors.horizontalCenter: ( (yourModel.count % 2) != 0 && (yourModel.count-1) == index) ? yourGridView.horizontalCenter : undefined
    

    Below is a demonstrative code how is can be used:

    Window {
        visible: true
        width: 800
        height: 600
        title: qsTr("Hello World")
    
        ListModel { id: rectModel}
    
        property int _spacing: 8
        property variant arrayColor: ["blue", "red", "yellow", "pink"]
    
        GridView {
            id: gridView
            width: 400; height: 400
            anchors {
                top: parent.top
                horizontalCenter: parent.horizontalCenter
            }
            cellWidth: width/2; cellHeight: height/4
            model: rectModel
            delegate: Rectangle{
                width: (parent.width - _spacing) / 2
                height: gridView.height/4 - _spacing / 2
                color: model.color
                // apply horizontal center if has impar elements and is the last element
                anchors.horizontalCenter: ( (rectModel.count % 2) != 0 && (rectModel.count-1) == index) ? parent.horizontalCenter : undefined
            }
        }
    
        Rectangle{
            id: buttonAdd
            anchors.top: gridView.bottom
            anchors.topMargin: 15
            anchors.horizontalCenter: gridView.horizontalCenter
            anchors.horizontalCenterOffset: -(width/2 + 2)
            width: 150
            height: 35
            color: "white"
            border.color: "gray"
            Text{
                anchors.centerIn: parent
                text: "ADD"
            }
    
            MouseArea{
                anchors.fill:parent
                onClicked: {
                    if(rectModel.count < 8)
                    rectModel.append({color: arrayColor[Math.floor(Math.random()*4)]})
                }
            }
        }
    
        Rectangle{
            id: buttonDel
            anchors.top: gridView.bottom
            anchors.topMargin: 15
            anchors.horizontalCenter: gridView.horizontalCenter
            anchors.horizontalCenterOffset: width / 2 + 2
            width: 150
            height: 35
            color: "white"
            border.color: "gray"
            
            Text{
                anchors.centerIn: parent
                text: "Del"
            }
    
            MouseArea{
                anchors.fill:parent
                onClicked: {
                    if(rectModel.count)
                        rectModel.remove(rectModel.count-1);
                }
            }
        }
    }
    

Log in to reply