GridLayout inside a StackView won't size properly
-
I'm creating a StackView, and using a GridLayout as one of the elements in the stack. When I do this, I can't get the layout of the GridLayout to look correct. All my columns are stacked on top of each other. I'm trying not to use absolute widths, so that my GridLayout will resize when the window is resized.
I suspect that there's something about the GridLayout I'm not understanding.
In my main:
StackView { id: stack anchors.fill: parent } Component.onCompleted:{ stack.push(page2, {immediate:true}, page1, {immediate:true}]) } Component { id: page1 Page1{} } Component { id: page2 Page2{} }
In Page1:
Item { id: page1 GridLayout{ id: grid columns: 3 Rectangle{ id: theRect Layout.column: 0 Layout.columnSpan: 1 color:"lightgrey" anchors.fill:parent } Text { id: text1 text: qsTr("page 1") font.pixelSize: 72 Layout.column: 1 Layout.columnSpan: 1 } BusyIndicator { id: busyIndicator anchors.fill:parent Layout.column: 2 Layout.columnSpan: 1 } }
The outcome is shows all three columns of the GridLayout on top of each other when shown by the StackView. If I give my GridLayout absolute height and width, I can begin to separate elements into different columns, but I want the column widths to be dynamic, not static.
Has anyone tried this with success?
-
GridLayout{ id: grid columns: 3 anchors.fill:parent //fills the parent item ... Rectangle{ id: theRect Layout.column: 0 Layout.columnSpan: 1 color:"lightgrey" //anchors.fill:parent No no! Not compatible with being a child of a layout! Layout.fillWidth:true //yes, if wanted Layout.fillHeight:true //yes, if wanted }
-
@Eeli-K said in GridLayout inside a StackView won't size properly:
Layout.fillWidth:true
That's an interesting idea.
I tried it, and I still have the problem where all three elements in the GridLayout are stacked on top of each other. The change is that these elements are now the same size as the screen.Thus, the StackView is correctly anchored to the window, and the GridView is correctly anchored to the stack view.
When the GridView is constructed, it's not part of the view hierarchy, and so perhaps it can't establish a correct size of the columns relative to the window. The GridView does get resized to fill the window, but the size and positions of the columns do not, so they stay at 0,0, and expand to match the size of their parent.
What I need is a delegate function that can be called when the GridView is resized, where I can recalculate the size of the columns. I could do the by adding an onHeightChanged or onWidthChanged signal handler, but I'm not sure how to force the GridLayout to change the size or position of it's child columns. Maybe setting the Layout.preferredHeight and Layout.preferredWidth would do that? I'll give it a shot.
-
@igor_stravinsky Did you remove anchors from all three children of the layout? If you use anchors.fill:parent in a direct child of a layout it will fill the layout, not just a cell, because the layout item is the parent. Cells are not parents of the children (I think there are no actual cell objects in a layout at all).
Get accustomed to Layout attached properties. If you want to set width for a column which is relative to the width of the whole layout item you can do for example this:
RowLayout{ id: layout Rectangle{Layout.preferredWidth: layout.width*0.33} Rectangle{Layout.fillWidth:true} }
and the first rect will use about 1/3 of the width and the second will take the rest.
-
@igor_stravinsky the reason why they're still stacked up because you still anchored the grid items to its parent. Like what @Eeli-K have said, make use of the Layout attached properties.
@igor_stravinsky said in GridLayout inside a StackView won't size properly:
Item {
id: page1GridLayout{ id: grid columns: 3 Rectangle{ id: theRect // no deed to specify the column because by default the flow of the GridLayout is from left to right //Layout.column: 0 //Layout.columnSpan: 1 // no need to add this becasue its default value is 1 color:"lightgrey" Layout.fillWidth: true //if you want this item to fill the remaining width after text1 and busyIndicator have been layed out. Layout.fillHeight: true // if you want this item to follow the maximum height of the all items. Otherwise, set its preferredWidth & preferredHeight //anchors.fill:parent } Text { id: text1 text: qsTr("page 1") font.pixelSize: 72 // use Layout:fillWidth and Layout.fillHeight depending on your desired layout, default value is false. //Layout.column: 1 //Layout.columnSpan: 1 } BusyIndicator { id: busyIndicator // use Layout:fillWidth and Layout.fillHeight depending on your desired layout, default value is false. //anchors.fill:parent //Layout.column: 2 //Layout.columnSpan: 1 }
}
-
I stripped things down and it turns I had a bug, which was that, as you guessed, I had an anchors.fill: parent line in the busyIndicator cell.
Once that was removed, I could see two of the three cells. It turns out that a rectangle doesn't have an intrinsic size, so setting Layout.fillWidth doesn't cause the rectangle in the first cell to show. To do that, I had to set the Layout.preferredWidth to a non-0 value.
Thanks for all the help!