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

positioning within a grid layout



  • Hi all -

    I'm trying to add to an existing QML view that utilizes a GridLayout. Here's the essential QML (I think):

    GridLayout {
        id: wellsGrid
        Repeater {
            model: wellPlateColNames.length * wellPlateRowNames.length
    
            Item {
                Layout.row: Math.floor(index / wellPlateColNames.length) + 1
                Layout.column: (index % wellPlateColNames.length) + (hideRowNames ? 0 : 1)
                Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
    
                Rectangle {
                    anchors.centerIn: parent
                    height: parent.height * root.wellCircleFromEnclosingRect
                    width: height
                    radius: height
                }
            }
        }
    

    This (correctly) produces this:
    nocaps.PNG
    I'm trying to add to this (currently just a pink rectangle per column; I'll get fancy when I get this working) with this code:

    Repeater { // this is at the same level as the repeater above
        id: columnCaps
        model: issViewModel.columnCapList
        Item {
            Layout.row: 0
            Layout.column: index + (hideRowNames ? 0 : 1)
            Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
    
            Rectangle {
                visible: true // modelData
                anchors.centerIn: parent
                //                        x: (wellsGrid.cellBasicWidth_ * index)
                //                        y: index - (50 * index)
                height: wellsGrid.cellBasicHeight_
                width: wellsGrid.cellBasicWidth_
                color: 'pink'
                Text {
                    id: colText
                    text: Number(index).toString()
                }
            }
        }
    }
    

    But I don't get the column positioning I'd expected:
    withcaps.PNG

    I inferred from the original code that specifying a column was enough to get the location I wanted; was I wrong about that?

    Thanks for any guidance...



  • Well, I solved that problem, but I'm not sure exactly why the fix worked. Here's the new QML:

    Repeater {
       id: columnCaps
       model: issViewModel.columnCapList
       Item {
          Layout.minimumHeight: wellsGrid.cellBasicHeight_
          Layout.minimumWidth: wellsGrid.cellBasicWidth_
          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 {
             visible: !modelData
             height: wellsGrid.cellBasicHeight_ * wellPlateRowNames.length
             width: wellsGrid.cellBasicWidth_
             color: 'pink'
             Text {
                id: colText
                text: "remove this cap"
             }
          }
       }
    }
    

    And it gives me this:
    plate.PNG

    This is a more direct copy of the code that creates the grid of circles. If I remove these lines:

        Layout.minimumHeight: wellsGrid.cellBasicHeight_
        Layout.minimumWidth: wellsGrid.cellBasicWidth_
    

    I don't get any columnar spacing. I'd be curious to know why not.



  • plate.PNG
    So...a follow-up question: below my grid (which is hidden under the bars), I want to put a legend for the colors of the bar. I'd like this to begin under the column labeled "1", but I'm not sure how to access that position.

    As a fallback, I'd be happy to use the position of the grid, and add a column width to this, but I'm having trouble converting the (real) number to something I can use in an anchor. Here's the relevant QML:

    // the grid layout
    GridLayout {
    id: wellsGrid
    
      // the wells
      Repeater {
        model: wellPlateColNames.length * wellPlateRowNames.length
        Item {
          Rectangle {
    	    // positioning and formatting here
          }
        }
      }
    } // end GridLayout
    
    // the legend.
    Row {
      anchors.top: verticalHighlight.bottom
      anchors.left: // WHAT TO DO HERE?
      Rectangle {
      ...
      }
      // more stuff to come here
    }
    

    So...assuming I can derive a numeric position, how do I use that number as the basis for an anchor?

    Thanks...



  • OK, after doing a little more research, I concluded that it's not possible to perform arithmetic operations on anchor elements. Since I didn't know how to derive position information on the grid elements, I just punted:

          Row {
              anchors.left: parent.left
              anchors.leftMargin: root.highlightedBarWidth_ // yes, this is a hack.
    

    Which gives me:
    plate.PNG

    I'm going to leave this as unsolved for another day or so, in the hopes that someone might have an idea on how to align with a column in the grid.



  • @mzimmers said in positioning within a grid layout:

    Repeater {
    id: columnCaps
    model: issViewModel.columnCapList
    Item {
    Layout.minimumHeight: wellsGrid.cellBasicHeight_
    Layout.minimumWidth: wellsGrid.cellBasicWidth_
    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 {
         visible: !modelData
         height: wellsGrid.cellBasicHeight_ * wellPlateRowNames.length
         width: wellsGrid.cellBasicWidth_
         color: 'pink'
         Text {
            id: colText
            text: "remove this cap"
         }
      }
    

    }
    }

    Add your legend inside your column caps.

    Item {
      id: legend
      visible: columnindex == 0
    
      //  how you can anchor to the column cap, and it doesn't have to be inside if you are not using clip
    }
    


  • @fcarney not sure I follow you. My column caps are:

    // column caps
    Repeater {
      id: columnCaps
      model: issViewModel.columnCapList
      Item {
    
      Rectangle {
      ...
    

    (I've left out the positioning and other stuff.)

    Anything I add to this will 1) exhaust the model and 2) be presented to the right of the current columns.

    Are you suggesting that I wrap my Repeater in an Item, and add the legend after the Repeater?

    Thanks...



  • @mzimmers said in positioning within a grid layout:

    Rectangle {

    Put the legend in the Rectangle in your repeater.
    Anchor it "outside" of the Rectangle.
    anchors.top: rectangle.bottom
    anchors.topMargin: 20



  • @fcarney like this?

    // column caps
    Repeater {
      id: columnCaps
      model: issViewModel.columnCapList
      Item {
       Rectangle {
         // the legend.
         Row { 
            visible: (navigationViewModel.screenId === screenName.newSynthesisPreview) && (columnindex === 1)
            anchors.top: parent.bottom
            anchors.left: parent.left
            anchors.topMargin: 20
    

    So...where does columnindex come from?

    Thanks...



  • @mzimmers said in positioning within a grid layout:

    So...where does columnindex come from?

    Repeater should have an index called "index". "columnindex" is pseudo code for whatever you have available that represents a column index.
    Is there a one to one relationship between the model of your repeater and your columns?



  • Sorry...got distracted by a phone call (plumbing emergency at home).

    @fcarney said in positioning within a grid layout:

    Is there a one to one relationship between the model of your repeater and your columns?

    This is the model:

      QVariantList m_columnCapList;
      Q_PROPERTY(QVariantList columnCapList
                     MEMBER m_columnCapList
                         NOTIFY columnCapsUpdated)
    

    This is actually an array of bools, one for each column. So I think the answer is "yes."

    EDIT: I tried using this:

    // column caps
    Repeater {
      id: columnCaps
      model: issViewModel.columnCapList
      Item {
        Rectangle {
          // the legend.
          Row {
            visible: (columnCaps.index === 0)
    

    But the legend doesn't display, so I guess I don't have this right.



  • Doh...I wish Creator would point out my QML errors to me a little more thoroughly...

      visible: (index === 0)
    

    This works.

    Thanks, fcarney.



  • In a View delegate index is a property defined in the delegate by the view. Sorry I was not more clear.
    https://doc.qt.io/qt-5/qml-qtquick-repeater.html#delegate-prop


Log in to reply