首页 > 解决方案 > 来自子元素委托的 QML 窗口大小

问题描述

我目前正在尝试为我正在计划的某个工具窗口创建一种通用 QML 组件。

有没有办法根据它包含的大小实际设置所述窗口的大小ListView?的大小ListView将部分取决于其委托渲染的模型数据。这是一个代码示例,它将从外部某处实例化:

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")
            }
        }
    }
}

所以基本上我试图访问例如list_entry.width作为窗口宽度的源,id因为委托可能会在初始 QML 实例化之后使用?不确定是否有办法,或者我不可避免地试图建立某种参考循环。谢谢!

标签: qtqml

解决方案


我不认为它会起作用。我尝试解决您的问题的第一步是使用contentWidth,但http://doc.qt.io/qt-5/qml-qtquick-listview.html#flickable-direction说:

默认情况下,垂直 ListView 将 flickableDirection 设置为 Flickable.Vertical,而水平 ListView 将其设置为 Flickable.Horizo​​ntal。此外,垂直 ListView 仅计算(估计)contentHeight,水平 ListView 仅计算 contentWidth。另一个维度设置为 -1。

所以你必须设置contentWidth自己,因为你使用的是垂直的ListView。如果您尝试仅使用默认值contentWidth

     width: list.contentWidth

窗口将没有宽度。所以,最好的解决方案可能是设置一个足够大的宽度:

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")
            }
        }
    }
}

你不一定要猜测它。例如,您可以使用 egTextMetrics来计算您期望的最大文本宽度。尽管您仍然需要考虑RowLayout.

如果您可以使用除 之外的其他类型ListView,则可以考虑例如Repeater在 aColumnLayout中,因为您可以使用它的implicitWidthandimplicitHeight属性来代替:

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")
                }
            }
        }
    }
}

推荐阅读