1
votes

I'm currently trying to create a sort of generic QML component for some tool window I'm planning.

Is there a way to actually set the size of said window according to the size of the ListView it contains? The size of the ListView would be partly dependent on the model data that its delegate is rendering. Here is a code example, which would be instantiated from somewhere outside:

import QtQuick 2.2
import QtQuick.Window 2.2
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.3

Window{
    id:window
    title: "WindowTitle"
    modality: "ApplicationModal"
    flags: "Dialog"

    ListView {
        id: list
        model: model_inst

        delegate: RowLayout{
            id: list_entry
            Text {
                text: "Model-based variable length text: " + text
            }
            ComboBox {
                model: listrole
            }
            Switch {
               text: qsTr("Switch")
            }
        }
    }
}

So basically I am trying to access e.g. list_entry.width as a source for the window width as id does not work since the delegate will probably be used after the initial QML instantiation? Not sure if there is a way at all or I'm inevitably trying to build some sort of reference loop. Thanks!

1

1 Answers

2
votes

I don't think it will work. The first step I tried in trying to solve your problem was to use contentWidth, but http://doc.qt.io/qt-5/qml-qtquick-listview.html#flickable-direction says:

By default, a vertical ListView sets flickableDirection to Flickable.Vertical, and a horizontal ListView sets it to Flickable.Horizontal. Furthermore, a vertical ListView only calculates (estimates) the contentHeight, and a horizontal ListView only calculates the contentWidth. The other dimension is set to -1.

So you have to set contentWidth yourself since you're using a vertical ListView. If you try to just use the default contentWidth:

     width: list.contentWidth

the window will have no width. So, the best solution is probably to set a width large enough:

import QtQuick 2.2
import QtQuick.Window 2.2
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.3

Window {
    id: window
    title: "WindowTitle"
    modality: "ApplicationModal"
    flags: "Dialog"
    width: list.contentWidth
    height: list.contentHeight
    visible: true

    ListView {
        id: list
        model: 10
        contentWidth: 400
        anchors.fill: parent

        delegate: RowLayout {
            Text {
                text: "Model-based variable length text: " + index
            }
            ComboBox {
                model: 10
            }
            Switch {
               text: qsTr("Switch")
            }
        }
    }
}

You don't necessarily have to guess it though. You could use e.g. TextMetrics to calculate the maximum text width you're expecting, for example. Though you'd still need to account for the other controls in your RowLayout.

If you can use other types besides ListView, you could consider e.g. Repeater within a ColumnLayout, as then you could use its implicitWidth and implicitHeight properties instead:

import QtQuick 2.2
import QtQuick.Window 2.2
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.3

Window {
    id: window
    title: "WindowTitle"
    modality: "ApplicationModal"
    flags: "Dialog"
    width: columnLayout.implicitWidth
    height: columnLayout.implicitHeight
    visible: true

    ColumnLayout {
        id: columnLayout
        anchors.fill: parent

        Repeater {
            id: repeater
            model: 10

            delegate: RowLayout {
                Text {
                    text: "Model-based variable length text: " + index
                }
                ComboBox {
                    model: 10
                }
                Switch {
                   text: qsTr("Switch")
                }
            }
        }
    }
}