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. positioning within a grid...revisited
Forum Updated to NodeBB v4.3 + New Features

positioning within a grid...revisited

Scheduled Pinned Locked Moved Solved QML and Qt Quick
12 Posts 3 Posters 1.1k Views 1 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.
  • mzimmersM Offline
    mzimmersM Offline
    mzimmers
    wrote on last edited by
    #1

    Hi all -

    I got some help with this awhile back here, but evidently I didn't understand what I was doing, so I need to take it up again.

    The problem: I have a gridlayout in which I want to place rectangles over the columns, and circles in the rectangle, centered on the row and column. That's basically it.

    Here's my code (sorry it's so long; I edited it as much as I could:

    import QtGraphicalEffects 1.12
    import QtQuick 2.12
    import QtQuick.Controls 2.12
    import QtQuick.Controls.Universal 2.2
    import QtQuick.Layouts 1.14
    import libstyles 1.0
    
    Item {
      id: root
    
      property var wellPlateRowNames: ["A", "B", "C", "D", "E", "F", "G", "H"]
      property var wellPlateColNames: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"]
    
      property int nbrPlateRows: wellPlateRowNames.length
      property int nbrPlateCols: wellPlateColNames.length
    
        GridLayout {
        id: wellsGrid
        anchors.fill: parent
        columnSpacing: 0 // the default is non-zero!
        rowSpacing: 0
    
        anchors.margins: gridMargin_
        property double cellHeight: (wellsGrid.height - (gridMargin_ * 2)) / wellsGrid.rows
        property double cellWidth: (wellsGrid.width - (gridMargin_ * 2)) / wellsGrid.columns
    
        columns: root.nbrPlateCols + (hideRowNames ? 0 : 1)
        rows: root.nbrPlateRows + (hideColNames ? 0 : 1)
    
        // column caps
        Repeater {
          id: columnCapsRepeater
          model: issViewModel.columnCapList
          property var capHeight: parent.height
          Item {
    
          Layout.minimumHeight: wellsGrid.cellHeight
          Layout.minimumWidth: wellsGrid.cellWidth
          Layout.maximumHeight: Layout.minimumHeight
          Layout.maximumWidth: Layout.minimumWidth
    
          Layout.row: Math.floor(index / wellPlateColNames.length) + 1
          Layout.column: (index) + (hideRowNames ? 0 : 1)
          Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
    
          Rectangle {
            id: columnStrip
            function getHeight() {
              var wgh = wellsGrid.cellHeight
              var nr = root.nbrPlateRows + 1 // I don't know why this "+1" is needed.
              var h = wgh * nr
              var s = wellsGrid.rowSpacing
              s *= (root.nbrPlateRows - 1)
              h += s
              return h
            }
    
            height: getHeight()//wellsGrid.height * root.nbrRows
            width: wellsGrid.cellWidth
            radius: 3
            color: 'lightgray'
    
            // the individual caps on the cap column.
            ColumnLayout {
            id: capLayout
            function calculateSpacing () {
              var stripHeight = columnStrip.height
              var capHeight = wellsGrid.cellHeight * root.wellCircleFromEnclosingRect
              var totalSpacing = stripHeight - (capHeight * root.nbrPlateRows)
              var unitSpacing = totalSpacing / (root.nbrPlateRows - 1)
              return unitSpacing
            }
    
            spacing: calculateSpacing()
            onVisibleChanged: {
              if (visible) {
                calculateSpacing()
              }
            }
            Repeater {
              id: wellCaps
              model: wellPlateRowNames.length
    
              Layout.row: Math.floor(index / root.nbrPlateCols) + 1
              Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
              Rectangle {
                id: wellCap
                height: wellsGrid.cellHeight * root.wellCircleFromEnclosingRect
                width: height
                radius: height
                Layout.alignment: Qt.AlignHCenter
                border.color: 'dimgray'
                color: 'deeppink'
                }
              }
            }
    

    And here's what I'm getting:
    wellplate.PNG

    Can someone provide me with guidance on how to center within a grid? Thank you.

    J.HilkJ 1 Reply Last reply
    0
    • mzimmersM mzimmers

      Hi all -

      I got some help with this awhile back here, but evidently I didn't understand what I was doing, so I need to take it up again.

      The problem: I have a gridlayout in which I want to place rectangles over the columns, and circles in the rectangle, centered on the row and column. That's basically it.

      Here's my code (sorry it's so long; I edited it as much as I could:

      import QtGraphicalEffects 1.12
      import QtQuick 2.12
      import QtQuick.Controls 2.12
      import QtQuick.Controls.Universal 2.2
      import QtQuick.Layouts 1.14
      import libstyles 1.0
      
      Item {
        id: root
      
        property var wellPlateRowNames: ["A", "B", "C", "D", "E", "F", "G", "H"]
        property var wellPlateColNames: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"]
      
        property int nbrPlateRows: wellPlateRowNames.length
        property int nbrPlateCols: wellPlateColNames.length
      
          GridLayout {
          id: wellsGrid
          anchors.fill: parent
          columnSpacing: 0 // the default is non-zero!
          rowSpacing: 0
      
          anchors.margins: gridMargin_
          property double cellHeight: (wellsGrid.height - (gridMargin_ * 2)) / wellsGrid.rows
          property double cellWidth: (wellsGrid.width - (gridMargin_ * 2)) / wellsGrid.columns
      
          columns: root.nbrPlateCols + (hideRowNames ? 0 : 1)
          rows: root.nbrPlateRows + (hideColNames ? 0 : 1)
      
          // column caps
          Repeater {
            id: columnCapsRepeater
            model: issViewModel.columnCapList
            property var capHeight: parent.height
            Item {
      
            Layout.minimumHeight: wellsGrid.cellHeight
            Layout.minimumWidth: wellsGrid.cellWidth
            Layout.maximumHeight: Layout.minimumHeight
            Layout.maximumWidth: Layout.minimumWidth
      
            Layout.row: Math.floor(index / wellPlateColNames.length) + 1
            Layout.column: (index) + (hideRowNames ? 0 : 1)
            Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
      
            Rectangle {
              id: columnStrip
              function getHeight() {
                var wgh = wellsGrid.cellHeight
                var nr = root.nbrPlateRows + 1 // I don't know why this "+1" is needed.
                var h = wgh * nr
                var s = wellsGrid.rowSpacing
                s *= (root.nbrPlateRows - 1)
                h += s
                return h
              }
      
              height: getHeight()//wellsGrid.height * root.nbrRows
              width: wellsGrid.cellWidth
              radius: 3
              color: 'lightgray'
      
              // the individual caps on the cap column.
              ColumnLayout {
              id: capLayout
              function calculateSpacing () {
                var stripHeight = columnStrip.height
                var capHeight = wellsGrid.cellHeight * root.wellCircleFromEnclosingRect
                var totalSpacing = stripHeight - (capHeight * root.nbrPlateRows)
                var unitSpacing = totalSpacing / (root.nbrPlateRows - 1)
                return unitSpacing
              }
      
              spacing: calculateSpacing()
              onVisibleChanged: {
                if (visible) {
                  calculateSpacing()
                }
              }
              Repeater {
                id: wellCaps
                model: wellPlateRowNames.length
      
                Layout.row: Math.floor(index / root.nbrPlateCols) + 1
                Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
                Rectangle {
                  id: wellCap
                  height: wellsGrid.cellHeight * root.wellCircleFromEnclosingRect
                  width: height
                  radius: height
                  Layout.alignment: Qt.AlignHCenter
                  border.color: 'dimgray'
                  color: 'deeppink'
                  }
                }
              }
      

      And here's what I'm getting:
      wellplate.PNG

      Can someone provide me with guidance on how to center within a grid? Thank you.

      J.HilkJ Online
      J.HilkJ Online
      J.Hilk
      Moderators
      wrote on last edited by
      #2

      @mzimmers

      question: why do you even bother with a GridLayout, when you provide columns and rows with their own repeaters ?

      import QtGraphicalEffects 1.12
      import QtQuick 2.12
      import QtQuick.Controls 2.12
      import QtQuick.Controls.Universal 2.2
      import QtQuick.Layouts 1.12
      //import libstyles 1.0
      
      Item {
          id: root
      
          property var wellPlateRowNames: ["A", "B", "C", "D", "E", "F", "G", "H"]
          property var wellPlateColNames: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"]
      
          property int cellWidth: width / wellPlateRowNames.length
          property int cellHeight: height / wellPlateColNames.length
      
          Column{
              id:cols
      
              Repeater{
                  model: wellPlateColNames
      
                  delegate: Row{
                          id:row
                          property var colData: modelData
                          Repeater{
                              model: wellPlateRowNames
                              delegate: Item{
                                  width: cellWidth
                                  height: cellHeight
      
                                  Rectangle{
                                      anchors.centerIn: parent
                                      width: Math.min(cellWidth, cellHeight)
                                      height: width
                                      radius: height / 2
      
                                      color: "pink"
                                  }
                                  Text {
                                      anchors.centerIn: parent
                                      text: row.colData + modelData
                                  }
      
                              }
                          }
                      }
              }
      
          }
      
      }
      
      

      7b0ba6e8-021e-461f-b030-827b96e5c8a8-image.png


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      mzimmersM 1 Reply Last reply
      1
      • J.HilkJ J.Hilk

        @mzimmers

        question: why do you even bother with a GridLayout, when you provide columns and rows with their own repeaters ?

        import QtGraphicalEffects 1.12
        import QtQuick 2.12
        import QtQuick.Controls 2.12
        import QtQuick.Controls.Universal 2.2
        import QtQuick.Layouts 1.12
        //import libstyles 1.0
        
        Item {
            id: root
        
            property var wellPlateRowNames: ["A", "B", "C", "D", "E", "F", "G", "H"]
            property var wellPlateColNames: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"]
        
            property int cellWidth: width / wellPlateRowNames.length
            property int cellHeight: height / wellPlateColNames.length
        
            Column{
                id:cols
        
                Repeater{
                    model: wellPlateColNames
        
                    delegate: Row{
                            id:row
                            property var colData: modelData
                            Repeater{
                                model: wellPlateRowNames
                                delegate: Item{
                                    width: cellWidth
                                    height: cellHeight
        
                                    Rectangle{
                                        anchors.centerIn: parent
                                        width: Math.min(cellWidth, cellHeight)
                                        height: width
                                        radius: height / 2
        
                                        color: "pink"
                                    }
                                    Text {
                                        anchors.centerIn: parent
                                        text: row.colData + modelData
                                    }
        
                                }
                            }
                        }
                }
        
            }
        
        }
        
        

        7b0ba6e8-021e-461f-b030-827b96e5c8a8-image.png

        mzimmersM Offline
        mzimmersM Offline
        mzimmers
        wrote on last edited by mzimmers
        #3

        @J-Hilk to answer your question, I inherited this view from another developer, so I'm not sure why a lot of stuff is in here. But, given how much time I've spent on trying to fix their stuff, it might be better to start from scratch.

        So, regarding your example, I have a few questions:

        1. your rows and columns are interchanged. I tried fixing it like this:
            Row {
                id: rows
                Repeater {
                    model: wellPlateColNames
        
                    delegate: Column {
                        id: columns
                        property var colData: modelData
                        Repeater {
                            model: wellPlateRowNames
                            delegate: Item {
                                width: cellWidth
                                height: cellHeight
        
                                Rectangle {
                                    anchors.centerIn: parent
                                    width: cellWidth
                                    height: width
                                    radius: height / 2
                                    color: "pink"
                                }
                                Text {
                                    anchors.centerIn: parent
                                    text: modelData + columns.colData
                                }
                            }
                        }
                    }
                }
            }
        

        But I only get one row to display. What am I doing wrong?
        onerow.PNG
        2. Why, in your output, are there gaps between the columns and not between the rows?
        3. Why is it necessary to use the intermediate delegate: Item, and not just repeat on a Rectangle? From the docs, it seems as though the only thing the delegate does for you is expose an index, but I don't see that we're using it in this example.

        Thanks...

        EDIT: I found the answer to #2 above:

         property int cellWidth: width / wellPlateRowNames.length
         property int cellHeight: height / wellPlateColNames.length
        

        Should be:

         property int cellWidth: width / wellPlateColNames.length
         property int cellHeight: height / wellPlateRowNames.length
        

        EDIT 2: #1 is answered; I got the vertical repeater working; was missing a delegate...I guess that answers my question #3 as well.

        1 Reply Last reply
        0
        • mzimmersM Offline
          mzimmersM Offline
          mzimmers
          wrote on last edited by
          #4

          So...my "dots" are now displaying properly. (I've got a bunch of changes I need to make to them, but I'll ignore that for now.)

          wellplate.PNG

          This display is (optionally) supposed to display the row and column headers as well. I've disabled the dots, and tried doing the same thing that J.Hilk showed above for the headers (disabling the dots for now), but I get this:

          headers.PNG

          Can someone tell me why they aren't spreading out? Thanks...

          1 Reply Last reply
          0
          • mzimmersM Offline
            mzimmersM Offline
            mzimmers
            wrote on last edited by mzimmers
            #5

            I've reduced this as much as possible, but the file's still sort of long; sorry.

            This code:

            import QtQuick 2.12
            import libstyles 1.0
            
            Item {
                id: root
            
                property var wellPlateRowNames: ["A", "B", "C", "D", "E", "F", "G", "H"]
                property var wellPlateColNames: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"]
            
                property double cellHeight: height / wellPlateRowNames.length
                property double cellWidth: width / wellPlateColNames.length
            
                width: 720
                height: 480
            
                // column names
                Repeater {
                    model: wellPlateColNames
                    delegate: Item {
                        height: parent.cellHeight * 0.67
                        width: parent.cellWidth
            
                        Rectangle {
                            Text {
                                anchors.fill: parent
                                anchors.centerIn: parent
                                text: wellPlateColNames[index]
                                color: 'black'
                                verticalAlignment: Text.AlignVCenter
                                horizontalAlignment: Text.AlignHCenter
                            }
                        }
                    }
                }
            
                Column {
                    Repeater {
                        model: wellPlateRowNames
                        delegate: Row {
                            id: rows
                            property var colData: modelData
                            Repeater {
                                model: wellPlateColNames
                                delegate: Item {
                                    width: cellWidth
                                    height: cellHeight
            
                                    Rectangle {
                                        anchors.centerIn: parent
                                        width: cellWidth
                                        height: width
                                        radius: height / 2
                                        color: "pink"
                                    }
                                    Text {
                                        anchors.centerIn: parent
                                        text: rows.colData + modelData
                                    }
                                }
                            }
                        }
                    }
                }
            }
            

            Produces this:
            wellplate.PNG

            So, the wells (the pink circles) are displaying correctly, but the column names are not. Can someone please tell me what I'm doing wrong in the first repeater?

            Oh: notice the little black rectangle in the very upper left; I think that's all the column names sitting on top of each other.

            Thanks...

            KroMignonK 1 Reply Last reply
            0
            • mzimmersM Offline
              mzimmersM Offline
              mzimmers
              wrote on last edited by mzimmers
              #6

              OK, through sheer trial and error, I got my column headings to appear (I removed the wells for the example):

              import QtQuick 2.12
              
              Item {
                  id: root
              
                  property var wellPlateColNames: ["", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"]
                  property double cellSize: 60 // nominal; expected to be overridden
                  width: cellSize * wellPlateColNames.length
                  height: cellSize * wellPlateRowNames.length
              
                  // column names
                  Row {
                      Repeater {
                          model: wellPlateColNames
                          delegate: Item {
                              height: cellSize
                              width: cellSize
                            Rectangle {
                                  anchors.centerIn: parent
                                  Text {
                                      anchors.centerIn: parent
                                      text: wellPlateColNames[index]
                                      color: 'black'
                                      verticalAlignment: Text.AlignVCenter
                                      horizontalAlignment: Text.AlignHCenter
                                  }
                              }
                          }
                      }
                  }
              }
              

              columns.PNG

              So...having both an Item and a Rectangle within my Repeater seems a bit redundant. When I try to eliminate either, though, I get a QML error "QML Row: Cannot specify left, right, horizontalCenter, fill or centerIn anchors for items inside Row. Row will not function." Is the use of both an Item and Rectangle a technique to get around this? If so, is there a preferred method of doing this?

              Thanks...

              J.HilkJ 1 Reply Last reply
              0
              • mzimmersM mzimmers

                OK, through sheer trial and error, I got my column headings to appear (I removed the wells for the example):

                import QtQuick 2.12
                
                Item {
                    id: root
                
                    property var wellPlateColNames: ["", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"]
                    property double cellSize: 60 // nominal; expected to be overridden
                    width: cellSize * wellPlateColNames.length
                    height: cellSize * wellPlateRowNames.length
                
                    // column names
                    Row {
                        Repeater {
                            model: wellPlateColNames
                            delegate: Item {
                                height: cellSize
                                width: cellSize
                              Rectangle {
                                    anchors.centerIn: parent
                                    Text {
                                        anchors.centerIn: parent
                                        text: wellPlateColNames[index]
                                        color: 'black'
                                        verticalAlignment: Text.AlignVCenter
                                        horizontalAlignment: Text.AlignHCenter
                                    }
                                }
                            }
                        }
                    }
                }
                

                columns.PNG

                So...having both an Item and a Rectangle within my Repeater seems a bit redundant. When I try to eliminate either, though, I get a QML error "QML Row: Cannot specify left, right, horizontalCenter, fill or centerIn anchors for items inside Row. Row will not function." Is the use of both an Item and Rectangle a technique to get around this? If so, is there a preferred method of doing this?

                Thanks...

                J.HilkJ Online
                J.HilkJ Online
                J.Hilk
                Moderators
                wrote on last edited by
                #7

                @mzimmers hey, sorry for the late reply, long weekend, little bit of sickness, mothers day etc. 😳

                Well, first of great that you managed to understand and evolve the (basic) example I provided, not looking to bad !

                To answer some of your questions:

                its probably best to answer with an other example, you're looking for an outer display of row names and column names, that can be toggled on and off

                import QtQuick 2.12
                
                Item {
                    id: root
                
                    property var wellPlateRowNames: ["A", "B", "C", "D", "E", "F", "G", "H"]
                    property var wellPlateColNames: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"]
                
                    property double cellHeight: height / (wellPlateRowNames.length + (showHeader2 ? 1 : 0))
                    property double cellWidth: width / (wellPlateColNames.length + (showHeader1 ? 1 : 0))
                    Behavior on cellHeight { NumberAnimation{duration: 200 }}
                    Behavior on cellWidth { NumberAnimation{duration: 200 }}
                
                    property bool showHeader1: true
                    property bool showHeader2: true
                
                
                    Timer{
                        running:true
                        interval: 1000
                        repeat: true
                        onTriggered:{
                            showHeader1 = Math.round(Math.random() % 2)
                            showHeader2 = Math.round(Math.random() % 4)
                        }
                    }
                
                    // Row names
                    Column{
                        id:headerRow
                        anchors{
                            left: parent.left
                            right: undefined
                            top: headerCol.bottom
                            bottom: parent.bottom
                        }
                
                        width: showHeader1 ? cellWidth : 0
                        Behavior on width { NumberAnimation{duration: 200 }}
                
                        Repeater {
                            model: wellPlateRowNames
                            delegate: Rectangle { // Rectangle if you want white backround, item if you want transparency
                                height: cellHeight
                                width: cellWidth
                
                                Text {
                                    anchors.fill: parent
                                    anchors.centerIn: parent
                                    text: modelData
                                    color: 'black'
                                    verticalAlignment: Text.AlignVCenter
                                    horizontalAlignment: Text.AlignHCenter
                                }
                            }
                        }
                    }
                
                    // column names
                    Row{
                        id:headerCol
                        anchors{
                            left: headerRow.right
                            right: parent.right
                            top: parent.top
                            bottom: undefined
                        }
                
                        height: showHeader2 ? cellHeight : 0
                        Behavior on height { NumberAnimation{duration: 200 }}
                
                        Repeater {
                            model: wellPlateColNames
                            delegate: Item {
                                height: cellHeight
                                width: cellWidth
                
                                Text {
                                    anchors.fill: parent
                                    anchors.centerIn: parent
                                    text: modelData
                                    color: 'black'
                                    verticalAlignment: Text.AlignVCenter
                                    horizontalAlignment: Text.AlignHCenter
                                }
                            }
                        }
                    }
                
                
                    Column {
                        anchors{
                            left: headerRow.right
                            right: parent.right
                            top: headerCol.bottom
                            bottom: parent.bottom
                        }
                        Repeater {
                            model: wellPlateRowNames
                            delegate: Row {
                                id: rows
                                property var colData: modelData
                                Repeater {
                                    model: wellPlateColNames
                                    delegate: Item {
                                        width: cellWidth
                                        height: cellHeight
                
                                        Rectangle {
                                            anchors.centerIn: parent
                                            width: cellWidth
                                            height: width
                                            radius: height / 2
                                            color: "pink"
                                        }
                                        Text {
                                            anchors.centerIn: parent
                                            text: rows.colData + modelData
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                
                

                I added a timer to randomly turn the headers on and off

                Can someone please tell me what I'm doing wrong in the first repeater

                the Repater doesn't fill a layout or column/row and you don't give the delegates of the repeater width/height or x/y yourself so they all stack. In the example I simply used an extra column/row to manage that

                So...having both an Item and a Rectangle within my Repeater seems a bit redundant. When I try to eliminate either, though, I get a QML error "QML Row: Cannot specify left, right, horizontalCenter, fill or centerIn anchors for items inside Row. Row will not function."

                In the example I fixed that,

                You could potentially get around the double item/rectangle for the main row/col view as well, but than you need to manage the spacing property of row/col to fix spacing issues, that we currently circumvent by filling the extra space with an invisible item :D

                hope this helps!

                Btw. Row/Col solution is one of many and simply the first one that came to my mind, a grid view or a proper model and tableview may actually better suited for your case here. In case you want to do it right and not fast :D


                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                Q: What's that?
                A: It's blue light.
                Q: What does it do?
                A: It turns blue.

                mzimmersM 1 Reply Last reply
                1
                • mzimmersM mzimmers

                  I've reduced this as much as possible, but the file's still sort of long; sorry.

                  This code:

                  import QtQuick 2.12
                  import libstyles 1.0
                  
                  Item {
                      id: root
                  
                      property var wellPlateRowNames: ["A", "B", "C", "D", "E", "F", "G", "H"]
                      property var wellPlateColNames: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"]
                  
                      property double cellHeight: height / wellPlateRowNames.length
                      property double cellWidth: width / wellPlateColNames.length
                  
                      width: 720
                      height: 480
                  
                      // column names
                      Repeater {
                          model: wellPlateColNames
                          delegate: Item {
                              height: parent.cellHeight * 0.67
                              width: parent.cellWidth
                  
                              Rectangle {
                                  Text {
                                      anchors.fill: parent
                                      anchors.centerIn: parent
                                      text: wellPlateColNames[index]
                                      color: 'black'
                                      verticalAlignment: Text.AlignVCenter
                                      horizontalAlignment: Text.AlignHCenter
                                  }
                              }
                          }
                      }
                  
                      Column {
                          Repeater {
                              model: wellPlateRowNames
                              delegate: Row {
                                  id: rows
                                  property var colData: modelData
                                  Repeater {
                                      model: wellPlateColNames
                                      delegate: Item {
                                          width: cellWidth
                                          height: cellHeight
                  
                                          Rectangle {
                                              anchors.centerIn: parent
                                              width: cellWidth
                                              height: width
                                              radius: height / 2
                                              color: "pink"
                                          }
                                          Text {
                                              anchors.centerIn: parent
                                              text: rows.colData + modelData
                                          }
                                      }
                                  }
                              }
                          }
                      }
                  }
                  

                  Produces this:
                  wellplate.PNG

                  So, the wells (the pink circles) are displaying correctly, but the column names are not. Can someone please tell me what I'm doing wrong in the first repeater?

                  Oh: notice the little black rectangle in the very upper left; I think that's all the column names sitting on top of each other.

                  Thanks...

                  KroMignonK Offline
                  KroMignonK Offline
                  KroMignon
                  wrote on last edited by KroMignon
                  #8

                  @mzimmers said in positioning within a grid...revisited:

                  I've reduced this as much as possible, but the file's still sort of long; sorry.

                  I think you should take time to read Qt documentation about "positionner" and "layout": https://doc.qt.io/qt-5/qtquick-usecase-layouts.html

                  In your first try, you used only a repeater, so you will use "Manual Positioning". In this case, you have to specify yourself X and Y position of each item. Per default, X=0 and Y=0, so everything is on same position!

                  Row in combination with repeater, you are using a "Positionner". The positioner will upate those coodinates for you.

                  Another solution could be to use a Layout, so you could add spacings between each item and handle automatic resizing of the items.

                  It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                  1 Reply Last reply
                  1
                  • J.HilkJ J.Hilk

                    @mzimmers hey, sorry for the late reply, long weekend, little bit of sickness, mothers day etc. 😳

                    Well, first of great that you managed to understand and evolve the (basic) example I provided, not looking to bad !

                    To answer some of your questions:

                    its probably best to answer with an other example, you're looking for an outer display of row names and column names, that can be toggled on and off

                    import QtQuick 2.12
                    
                    Item {
                        id: root
                    
                        property var wellPlateRowNames: ["A", "B", "C", "D", "E", "F", "G", "H"]
                        property var wellPlateColNames: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"]
                    
                        property double cellHeight: height / (wellPlateRowNames.length + (showHeader2 ? 1 : 0))
                        property double cellWidth: width / (wellPlateColNames.length + (showHeader1 ? 1 : 0))
                        Behavior on cellHeight { NumberAnimation{duration: 200 }}
                        Behavior on cellWidth { NumberAnimation{duration: 200 }}
                    
                        property bool showHeader1: true
                        property bool showHeader2: true
                    
                    
                        Timer{
                            running:true
                            interval: 1000
                            repeat: true
                            onTriggered:{
                                showHeader1 = Math.round(Math.random() % 2)
                                showHeader2 = Math.round(Math.random() % 4)
                            }
                        }
                    
                        // Row names
                        Column{
                            id:headerRow
                            anchors{
                                left: parent.left
                                right: undefined
                                top: headerCol.bottom
                                bottom: parent.bottom
                            }
                    
                            width: showHeader1 ? cellWidth : 0
                            Behavior on width { NumberAnimation{duration: 200 }}
                    
                            Repeater {
                                model: wellPlateRowNames
                                delegate: Rectangle { // Rectangle if you want white backround, item if you want transparency
                                    height: cellHeight
                                    width: cellWidth
                    
                                    Text {
                                        anchors.fill: parent
                                        anchors.centerIn: parent
                                        text: modelData
                                        color: 'black'
                                        verticalAlignment: Text.AlignVCenter
                                        horizontalAlignment: Text.AlignHCenter
                                    }
                                }
                            }
                        }
                    
                        // column names
                        Row{
                            id:headerCol
                            anchors{
                                left: headerRow.right
                                right: parent.right
                                top: parent.top
                                bottom: undefined
                            }
                    
                            height: showHeader2 ? cellHeight : 0
                            Behavior on height { NumberAnimation{duration: 200 }}
                    
                            Repeater {
                                model: wellPlateColNames
                                delegate: Item {
                                    height: cellHeight
                                    width: cellWidth
                    
                                    Text {
                                        anchors.fill: parent
                                        anchors.centerIn: parent
                                        text: modelData
                                        color: 'black'
                                        verticalAlignment: Text.AlignVCenter
                                        horizontalAlignment: Text.AlignHCenter
                                    }
                                }
                            }
                        }
                    
                    
                        Column {
                            anchors{
                                left: headerRow.right
                                right: parent.right
                                top: headerCol.bottom
                                bottom: parent.bottom
                            }
                            Repeater {
                                model: wellPlateRowNames
                                delegate: Row {
                                    id: rows
                                    property var colData: modelData
                                    Repeater {
                                        model: wellPlateColNames
                                        delegate: Item {
                                            width: cellWidth
                                            height: cellHeight
                    
                                            Rectangle {
                                                anchors.centerIn: parent
                                                width: cellWidth
                                                height: width
                                                radius: height / 2
                                                color: "pink"
                                            }
                                            Text {
                                                anchors.centerIn: parent
                                                text: rows.colData + modelData
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    
                    

                    I added a timer to randomly turn the headers on and off

                    Can someone please tell me what I'm doing wrong in the first repeater

                    the Repater doesn't fill a layout or column/row and you don't give the delegates of the repeater width/height or x/y yourself so they all stack. In the example I simply used an extra column/row to manage that

                    So...having both an Item and a Rectangle within my Repeater seems a bit redundant. When I try to eliminate either, though, I get a QML error "QML Row: Cannot specify left, right, horizontalCenter, fill or centerIn anchors for items inside Row. Row will not function."

                    In the example I fixed that,

                    You could potentially get around the double item/rectangle for the main row/col view as well, but than you need to manage the spacing property of row/col to fix spacing issues, that we currently circumvent by filling the extra space with an invisible item :D

                    hope this helps!

                    Btw. Row/Col solution is one of many and simply the first one that came to my mind, a grid view or a proper model and tableview may actually better suited for your case here. In case you want to do it right and not fast :D

                    mzimmersM Offline
                    mzimmersM Offline
                    mzimmers
                    wrote on last edited by
                    #9

                    @J-Hilk that's a good example...thanks. I tweaked it slightly for reasons I hadn't bothered to share, but it works.

                    After looking at your example, I realized I was making a mistake by reusing the name of the data model ("wells"). That's fixed, but something's now wrong with the way I access the model.

                    I need to determine the color of the well (the dot) based on a property in the model. The model is defined as:

                      Q_PROPERTY(QQmlListProperty<dnas::Well> wells READ GetWells NOTIFY EventWellsUpdated)
                    

                    This worked before my re-write, but now I don't seem to be able to extract a valid index from the model. Here's a code snippet:

                    Item {
                        id: root
                        property var wells: null // provided by caller
                        property var wellPlateRowNames: ["A", "B", "C", "D", "E", "F", "G", "H"]
                        property var wellPlateColNames: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"]
                    	
                        function getColor(index) {
                            var color
                            color = Utils.getColorByWellState(wells[index].seqState, wells[index].yieldState, useSeqColors)
                            return color
                        }
                        Column {
                            Repeater {
                                model: wellPlateRowNames
                                delegate: Row {
                                    Repeater {
                                        model: wellPlateColNames
                                        delegate: Item {
                                            Rectangle {
                                                color: root.getColor(root.wells.index)
                    

                    When I go through the getColor() function in the debugger, the argument index is always undefined. I'm almost positive the model is good...what am I doing wrong here?

                    Thanks.

                    1 Reply Last reply
                    0
                    • mzimmersM Offline
                      mzimmersM Offline
                      mzimmers
                      wrote on last edited by
                      #10

                      Well, I'm still not sure how I broke the wells.index value, but I've worked around it with this:

                      Repeater {
                          model: wellPlateRowNames
                          delegate: Row {
                              id: wellRows
                              property var i: index
                              property var colData: modelData
                              Repeater {
                                  model: wellPlateColNames
                                  delegate: Item {
                                      id: colInRow
                                      property var i: index
                      
                                      Rectangle {
                                          property int i: (colInRow.i * 12) + wellRows.i
                                          color: root.getColor(i)
                      

                      Certainly not the most elegant solution, but it works. Still, I'd like to know if anyone sees a problem with my prior effort.

                      Thanks...

                      1 Reply Last reply
                      0
                      • mzimmersM Offline
                        mzimmersM Offline
                        mzimmers
                        wrote on last edited by
                        #11

                        I decided that using a Grid was a more natural implementation:

                            Grid {
                                id: wellsGrid
                                columns: nbrColsInPlate
                                columnSpacing: 0 // the default is non-zero!
                                rowSpacing: 0
                                anchors {
                                    left: columnOfRowNbrs.right
                                    right: parent.right
                                    top: rowOfColNbrs.bottom
                                    bottom: parent.bottom
                                }
                                Repeater {
                                    model: wells
                                    delegate: Item {
                                        width: cellWidth
                                        height: cellHeight
                        
                                        // the well.
                                        Rectangle {
                                            anchors.centerIn: parent
                                            width: wellWidth
                                            height: width
                                            radius: height / 2
                                            color: root.getColor(index)
                                        }
                        

                        This works great for the individual cells. Now, I need to add to this view, by (selectively) drawing rectangles over the columns. I've looked at the Grid docs, but I don't see a way to reference a particular column, and therefore no way to center these rectangles. Am I going to have to use manual positioning?

                        Thanks...

                        1 Reply Last reply
                        0
                        • mzimmersM Offline
                          mzimmersM Offline
                          mzimmers
                          wrote on last edited by
                          #12

                          I don't know if this is a particularly good way to do it, but I managed to make it work like this:

                            Repeater {
                              id: columnCapsRepeater
                              model: issViewModel.columnCapList
                              property var capHeight: parent.height
                              Item {
                                x: (cellWidth * index) + (hideColNames ? 0 : (cellWidth * headingSizeRatio))
                                y: hideRowNames ? 0 : (cellHeight * headingSizeRatio)
                                height: cellHeight * nbrRowsInPlate
                                width: cellWidth
                          	  
                                Rectangle {
                                  id: capStrip
                                  height: parent.height
                                  width: parent.width
                                  anchors.fill: parent
                                  anchors.leftMargin: cellWidth * 0.02
                                  anchors.rightMargin: cellWidth * 0.02
                                  radius: width * 0.1
                                  color: 'lightgray'
                                }
                          

                          I welcome any feedback on this approach. Thanks to everyone for the help!

                          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