limiting spaced used by a ListView
-
Hi all -
Awhile back, I asked a similar question, but now I have a new issue: I want to size my ListView to use as much space as necessary BUT not so much that it will cause items below the ListView to be hidden. In this example:
import QtQuick import QtQuick.Controls import QtQuick.Layouts ApplicationWindow { id: window width: 640 height: 480 visible: true ColumnLayout { id: columnLayout readonly property int spacingValue: 8 spacing: spacingValue width: window.width Rectangle { id: topRect; height: 40; width: window.width; color: 'red' } ListView { Layout.preferredHeight: contentHeight property int availHeight: window.height - topRect.height - bottomRect.height - columnLayout.spacingValue * 2 Layout.maximumHeight: Math.min(contentHeight, availHeight) width: window.width clip: true spacing: 8 model: 5 delegate: Rectangle { height: 100 width: parent.width color: 'green' } } Rectangle { id: bottomRect; height: 40; width: window.width; color: 'blue' } } }
Is there some way I can avoid having to manually calculate the maximum height as I do with the availHeight property?
Thanks...
-
Hi
Maybe I'm reading too fast, but I don't understand why you don't simply just use anchors.
If I understand it right, the top Rectangle serves as a header, and the bottom one as a Footer
I would simply use anchor the header rectangle top / left / right to it's parent, same for the footer (bottom instead of top)
and anchor the top of the ListView to the bottom of the header, and conversely with the footer. And left/right to parent of course. And remove explicit width definition for those 3 items of course. Anchor.fill the ColumnLayout to it's own parent also. -
As far as I understand your problem, if all you want is the header rectangle at the top, the footer rectangle at the bottom, and the ListView taking all the space available between the two, then anchors just do the job. And probably way more appropriate than the ColumnLayout (at least in this case).
And contrarily to what I said before, don't anchor the ColumnLayout, get rid of it instead. Anchors or Layout, but not both at the same time. In this case, anchors are probably more appropriate than a Layout. At least in my opinion.
Here's your code reworked, I've nested the ListView in another Rectangle with border for visibility. This should work, however I can't test it at the moment, seems like stuff are broken on my device. I won't fix it now.
import QtQuick import QtQuick.Controls import QtQuick.Layouts Window { id: window width: 640 height: 480 visible: true // ColumnLayout // { // id: columnLayout // readonly property int spacingValue: 8 // spacing: spacingValue // width: window.width Rectangle { id: topRect height: 40 // define height explicitly, width is gonna be defined through anchors // width: window.width anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right anchors.margins: 2 color: 'red' } // Adding a rectangle with border just to show Rectangle { id: borderRect anchors.top: topRect.bottom anchors.left: parent.left anchors.right: parent.right anchors.bottom: bottomRect.top border.color: "cyan" ListView { // Layout.preferredHeight: contentHeight // property int availHeight: window.height // - topRect.height // - bottomRect.height // - columnLayout.spacingValue * 2 // Layout.maximumHeight: Math.min(contentHeight, // availHeight) // width: window.width anchors.fill: parent anchors.margins: 2 clip: true spacing: 8 model: 5 delegate: Rectangle { height: 100 width: parent.width color: 'green' } } } Rectangle { id: bottomRect height: 40 // Exactly the same than topRect, keep height, width determined from anchors // width: window.width anchors.bottom: parent.bottom anchors.left: parent.left anchors.right: parent.right anchors.margins: 2 color: 'blue' } // } }
And same for delegate : anchor L+R, define height. Or maybe not ? I'm having a doubt now. I now remember that some stuff don't like to be anchored, this might be one.
-
@ankou29666 said in limiting spaced used by a ListView:
if all you want is the header rectangle at the top, the footer rectangle at the bottom, and the ListView taking all the space available between the two
No, that's not what I want. I want in the following vertical order:
- a red rectangle (my header)
- an area with content of variable height, just below my red rectangle. The height of this area must not grow so great as to hide items below.
- a blue rectangle (my footer), immediately below #2 (NOT necessarily at the bottom of the screen).
I can do this with anchors or layouts, but either way, I'm forced to make a cumbersome maximum height calculation. This is what I'm trying to avoid.
-
Ok, so if I understand it right, you want the footer to remain at the bottom of the window WHEN the content of the ListView overfills the available space, and at the bottom of the ListView otherwise ?
In this case the anchoring way would require conditional anchoring (not even sure it's possible, never seen it, never tried it) depending on some height computations that's probably not going to be more simple than those you want to avoid. Likely to be the exact same formula I guess.
-
I'm not really sure this could achieve what you are looking for. but ListView has (header and) footer properties. also footerPositionning. Have you looked in that direction ?