Overview
I'm designing a Dialog
in QML. The header property uses a TabBar
to allow the user to select different pages in the dialog which are held in the contentItem property using StackLayout
. However when I open the dialog, its default visual components are sized to the smallest possible dimensions and the items in contentItem spill out the sides:
(Also of note is how low-contrast the default text is, but one issue at a time.)
The behavior I'd like to see is that the dialog loads with its dimensions set to the maximum of its child elements. That is, if the StackLayout
contains two items, one wider than the other, I would like Dialog
's width to accommodate the wider item, even if the less wide item is currently being displayed.
Code
Here's a minimal example showing this behavior:
main.qml
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls
import QtQuick.Layouts
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
Dialog {
id: myDialog
title: "Example Dialog"
modal: true
closePolicy: Popup.CloseOnEscape
standardButtons: Dialog.Ok | Dialog.Cancel
header: TabBar {
id: bar
TabButton {text: "Tab1"}
TabButton {text: "Tab2"}
}
contentItem: StackLayout {
currentIndex: bar.currentIndex
Item {
Rectangle {
color: "blue"
width: 100
height: 200
}
}
Item {
Rectangle {
color: "red"
width: 200
height: 100
}
}
}
}
Button {
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
text: "Open Dialog"
onPressed: myDialog.open()
}
}
What I've Tried
I've looked through the documentation for Dialog but didn't see any mention of how to manage its size. I also tried directly setting the Dialog
's height to implicitContentHeight implicitHeaderHeight
and width to implicitContentWidth
, but that caused the Dialog's visual components to disappear upon opening it. I don't think that the Dialog
type's dimensions are supposed to be directly set, that it should be allowed to automatically resize.
CodePudding user response:
The issue is that StackLayout doesn't know the implicit (or preferred) size of its items.
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
ApplicationWindow {
id: window
width: 640
height: 480
visible: true
Dialog {
id: myDialog
title: "Example Dialog"
modal: true
closePolicy: Popup.CloseOnEscape
standardButtons: Dialog.Ok | Dialog.Cancel
visible: true
header: TabBar {
id: bar
TabButton {text: "Tab1"}
TabButton {text: "Tab2"}
}
contentItem: StackLayout {
currentIndex: bar.currentIndex
Item {
implicitWidth: blueRect.implicitWidth
implicitHeight: blueRect.implicitHeight
Rectangle {
id: blueRect
color: "blue"
implicitWidth: 100
implicitHeight: 200
}
}
Item {
implicitWidth: redRect.implicitWidth
implicitHeight: redRect.implicitHeight
Rectangle {
id: redRect
color: "red"
implicitWidth: 200
implicitHeight: 100
}
}
}
}
}
You can also do:
Item {
Layout.preferredWidth: blueRect.implicitWidth
Layout.preferredHeight: blueRect.implicitHeight
// ...
Layouts and controls use implicit size to know what the implicit/default/natural size of the item should be.