ColumnLayout sizing policy and TableView maximum height limitation problem
-
Question about
ColumnLayoutand its sizing policy. I have several nested components withColumns (ColumnLayout) in my design. I want to organize UI to be resizable to restrictTableViewheight to fit within the app window. In other words, I want it to be anchored to the bottom of the main window (taking margins into account of course), but only if when there are a lot of rows, or ifTableViewis content is small, then it should not be anchored it to app window bottom.The container
Rectangle { id: frame }should be also anchored to the window bottom only ifTableViewis too big.Previously I had design with
Columns, then converted them toColumnLayoutwith spacerItemadded at main window bottom. Logic in code below works mostly fine, however have small issues I want to resolve:- if
tableFillHeightproperty is true - everything looks fine and works as expected; - if
tableFillHeightis false thentableViewbecome too big (overlapsRectangle { id: frame }so there is no bottom margin which is specified byframeColumnmargins property, andtotalRecordsTextdrawn below (overlaps)Rectangle {id: frame}too, while it should be inside it - so I assumeLayoutlogic some kind broken or incomplete there.
Could you please help me understand what might be wrong? Where did I miss something about the layout logic? Thanks!
ApplicationWindow { // top component property alias tableFillHeight: frame._fillHeight ColumnLayout { id: mainLayout anchors.fill: parent anchors.margins: defaultPixelHeight * 4 / 3 Text { id: appHeader Layout.topMargin: defaultPixelHeight * 4 / 3 Layout.fillWidth: true } Rectangle { // separate nested component id: frame Layout.fillWidth: true Layout.fillHeight: _fillHeight readonly property bool _fillHeight: { let bottomInMain = mapToItem(applicationWindow.contentItem, 0, implicitHeight).y return bottomInMain > (applicationWindow.height - mainLayout.anchors.margins) } implicitHeight: frameColumn.implicitHeight ColumnLayout { id: frameColumn anchors.fill: parent anchors.margins: defaultPixelHeight * 4 / 3 spacing: defaultPixelHeight Row { Text {} } Rectangle { id: serviceFrame Layout.fillWidth: true } ColumnLayout { // separate nested component Layout.fillWidth: true Layout.fillHeight: tableFillHeight spacing: defaultPixelHeight Row { Button {} } ColumnLayout { // separate nested component id: tableColumn Layout.fillWidth: true Layout.fillHeight: tableFillHeight implicitHeight: tableFillHeight ? -1 : tableColumn.implicitHeight spacing: 2 HorizontalHeaderView { id: header Layout.fillWidth: true syncView: tableView } TableView { id: tableView Layout.fillWidth: true Layout.fillHeight: tableFillHeight implicitHeight: contentItem.height } } Text { id: totalRecordsText text: qsTr("Total — ") + records_count.toString() } } } } Item { id: spacer Layout.fillWidth: true Layout.fillHeight: !tableFillHeight visible: !tableFillHeight } } }Summarizing:
✅
TableView(with its containingRectangle) should expand and fill remaining space only when its content is large.
✅ It should shrink when content is small.
✅ It must stay inside the Rectangle (frame) and not overflow.
✅totalRecordsTextmust stay visible insideframeas well and not overlap. - if
-
Solution was mostly there and fix appeared very simple:
- move anchors margins from
_fillHeightproperty calculations to
readonly property bool _fillHeight: { let bottom = mapToItem(applicationWindow.contentItem, 0, implicitHeight).y; return bottom > applicationWindow.height }frame.implicitHeightproperty:
implicitHeight: frameColumn.implicitHeight + defaultPixelHeight * 4Now everything works and looks fine! No errors or binding loops.
- move anchors margins from
-
A Aleksey_K has marked this topic as solved on