Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. GridLayout with equal sized cells
Forum Updated to NodeBB v4.3 + New Features

GridLayout with equal sized cells

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
8 Posts 3 Posters 9.9k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • DuBuD Offline
    DuBuD Offline
    DuBu
    wrote on last edited by
    #1

    Hi all,

    is there a way to force a GridLayout to keep the cells equally sized so I can use it as a real layout grid?
    Example:

    GridLayout {
      width: 100
      height: 100
      columns: 5
      rows: 5
      columnSpacing: 0
      rowSpacing: 0
      Rectangle {
        Layout.fillWidth: true
        Layout.fillHeight: true
        Layout.column: 2
        Layout.row: 1
      }
    }
    

    The rectangle in the example should sit at x = 40 and y = 20 and the size should be 20x20.

    1 Reply Last reply
    1
    • P Offline
      P Offline
      pderocco
      wrote on last edited by
      #2

      I know this is old, but someone might find this useful.

      You don't set the size of a GridLayout by setting rows and columns. The only purpose of rows or columns is to tell the layout engine when to wrap to the next column or row when auto-assigning row and column numbers. The GridLayout ultimately derives its size from the highest numbered row and column occupied.

      Furthermore, you have to actually put something into every row and column that has its fillWidth and fillHeight set to "inflate" those rows and columns to the desired size. You can do that by filling unused positions with dummy Item objects that have the necessary Layout properties. In fact, you only need to ensure that at least one position in each row and column is so occupied in order to force the layout.

      It's pretty easy to write your own fixed grid object in QML, derived from Item, or Rectangle if you want a background color. Its Component.onCompleted handler can iterate through its children and set the position and size of its children based on their Layout.column and Layout row properties, along with spacing and margins properties on your object. You could even support Layout.columnSpan and Layout rowSpan with some simple arithmetic.

      1 Reply Last reply
      0
      • DuBuD Offline
        DuBuD Offline
        DuBu
        wrote on last edited by
        #3

        I was trying to avoid the things you supposed to get GridLayout to do what I want. In the end I did what you supposed in your last paragraph, I wrote my own TableLayout component.

        1 Reply Last reply
        0
        • H Offline
          H Offline
          haftado3
          wrote on last edited by
          #4
          GridLayout{
              property bool showGridLines : true
              implicitHeight: 150
              implicitWidth: 150
              rowSpacing: 0
              columnSpacing: 0
              id:gridlayout
              Repeater{
                  id:repeater
                  model: gridlayout.rows*gridlayout.columns
                  delegate:Rectangle{
                      property var i : parseInt(index / gridlayout.rows)
                      property var j : index % gridlayout.columns
                      Layout.fillWidth:true
                      Layout.fillHeight:true
                      Layout.row: i
                      Layout.column: j
                      color:"transparent"
                      border.width: showGridLines?1:0
                  }
              }
          }
          

          0_1557478172939_dddss.PNG

          DuBuD P 2 Replies Last reply
          0
          • H haftado3
            GridLayout{
                property bool showGridLines : true
                implicitHeight: 150
                implicitWidth: 150
                rowSpacing: 0
                columnSpacing: 0
                id:gridlayout
                Repeater{
                    id:repeater
                    model: gridlayout.rows*gridlayout.columns
                    delegate:Rectangle{
                        property var i : parseInt(index / gridlayout.rows)
                        property var j : index % gridlayout.columns
                        Layout.fillWidth:true
                        Layout.fillHeight:true
                        Layout.row: i
                        Layout.column: j
                        color:"transparent"
                        border.width: showGridLines?1:0
                    }
                }
            }
            

            0_1557478172939_dddss.PNG

            DuBuD Offline
            DuBuD Offline
            DuBu
            wrote on last edited by
            #5

            @haftado3 What do you wanna show with your example?

            1 Reply Last reply
            0
            • H haftado3
              GridLayout{
                  property bool showGridLines : true
                  implicitHeight: 150
                  implicitWidth: 150
                  rowSpacing: 0
                  columnSpacing: 0
                  id:gridlayout
                  Repeater{
                      id:repeater
                      model: gridlayout.rows*gridlayout.columns
                      delegate:Rectangle{
                          property var i : parseInt(index / gridlayout.rows)
                          property var j : index % gridlayout.columns
                          Layout.fillWidth:true
                          Layout.fillHeight:true
                          Layout.row: i
                          Layout.column: j
                          color:"transparent"
                          border.width: showGridLines?1:0
                      }
                  }
              }
              

              0_1557478172939_dddss.PNG

              P Offline
              P Offline
              pderocco
              wrote on last edited by
              #6

              @haftado3 I think i needs gridlayout.columns in the denominator. It worked here because the number of rows and columns happened to be the same. You also don't need i and j, since you could just define Layout.row and Layout.column with the expressions. And you wouldn't need parseInt because the properties truncate to integers anyway. Finally, I think you could just use Item for the delegate, since that's pretty much the same thing as a transparent Rectangle.

              But anyway, don't you see lots of warnings in the log, when you place real items (like the small images) in the same cells as the repeated rectangles? That's a problem I've hoped to find a workaround for.

              H 1 Reply Last reply
              0
              • P pderocco

                @haftado3 I think i needs gridlayout.columns in the denominator. It worked here because the number of rows and columns happened to be the same. You also don't need i and j, since you could just define Layout.row and Layout.column with the expressions. And you wouldn't need parseInt because the properties truncate to integers anyway. Finally, I think you could just use Item for the delegate, since that's pretty much the same thing as a transparent Rectangle.

                But anyway, don't you see lots of warnings in the log, when you place real items (like the small images) in the same cells as the repeated rectangles? That's a problem I've hoped to find a workaround for.

                H Offline
                H Offline
                haftado3
                wrote on last edited by haftado3
                #7

                @pderocco first, item do not have border i guess , so i used transparent rectangle, i used parseInt to round down devide value, i created rectangle here to set fixed size for Grid columns and rows ,i and j was for debugging reasons and removed:
                FixGrid.qml

                GridLayout{
                    default property list<Item> childrens
                    Component.onCompleted: {
                        if(childrens != null){
                            for(var z = 0;z<childrens.length;++z){
                                var row = childrens[z].Layout.row
                                var col = childrens[z].Layout.column
                                var result = (row+1)*(col+1)
                                childrens[z].parent = gridlayout.children[result]
                            }
                        }
                    }
                
                    property bool showGridLines : false
                    implicitHeight: 150
                    implicitWidth: 150
                    rowSpacing: 0
                    columnSpacing: 0
                    id:gridlayout
                    Repeater{
                        id:repeater
                        model: gridlayout.rows*gridlayout.columns
                        delegate:Rectangle{
                            clip: true
                            Layout.fillHeight: true
                            Layout.fillWidth: true
                            Layout.row: parseInt(index / gridlayout.rows)
                            Layout.column: index % gridlayout.columns
                            color:"transparent"
                            border.width: showGridLines?1:0
                
                        }
                    }
                }
                

                this will work but some changes will be needed :

                FixGrid{
                        columns : 5
                        rows : 6
                        Button{
                              Layout.column : 2
                              Layout.row : 0
                        }
                }
                
                DuBuD 1 Reply Last reply
                0
                • H haftado3

                  @pderocco first, item do not have border i guess , so i used transparent rectangle, i used parseInt to round down devide value, i created rectangle here to set fixed size for Grid columns and rows ,i and j was for debugging reasons and removed:
                  FixGrid.qml

                  GridLayout{
                      default property list<Item> childrens
                      Component.onCompleted: {
                          if(childrens != null){
                              for(var z = 0;z<childrens.length;++z){
                                  var row = childrens[z].Layout.row
                                  var col = childrens[z].Layout.column
                                  var result = (row+1)*(col+1)
                                  childrens[z].parent = gridlayout.children[result]
                              }
                          }
                      }
                  
                      property bool showGridLines : false
                      implicitHeight: 150
                      implicitWidth: 150
                      rowSpacing: 0
                      columnSpacing: 0
                      id:gridlayout
                      Repeater{
                          id:repeater
                          model: gridlayout.rows*gridlayout.columns
                          delegate:Rectangle{
                              clip: true
                              Layout.fillHeight: true
                              Layout.fillWidth: true
                              Layout.row: parseInt(index / gridlayout.rows)
                              Layout.column: index % gridlayout.columns
                              color:"transparent"
                              border.width: showGridLines?1:0
                  
                          }
                      }
                  }
                  

                  this will work but some changes will be needed :

                  FixGrid{
                          columns : 5
                          rows : 6
                          Button{
                                Layout.column : 2
                                Layout.row : 0
                          }
                  }
                  
                  DuBuD Offline
                  DuBuD Offline
                  DuBu
                  wrote on last edited by
                  #8

                  @haftado3 Again, what do you want to show with your example? What is your "childrens" property good for? I think it doesn't solve the issue I had when I started the thread.

                  BTW: Using "parseInt" to round down a number value is not really performant. It converts your floating point value to a string and parses it. It's by far faster to use Math.floor. But I think in this case, "Layout.row" is an integer property, so you don't need to convert it explicitly, it's done implicitly when you assign a floating point value to it.

                  But again, is your code solving the issue the original post was about?

                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved