Home > Enterprise >  QML Dialog Not Resizing To Accommodate Content
QML Dialog Not Resizing To Accommodate Content

Time:08-24

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:

Dialog with components spilling 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.

  • Related