项目未正确分布在 GridLayout 中

Items not correctly spread across GridLayout

我有以下自定义 QML Item,它将表示一个 pin 码输入 GUI 元素:

import QtQuick 2.0
import QtQuick.Layouts 1.2
import QtQuick.Controls 1.3

import "../items"

Item
{
    id: ueKeypad

    width: 512
    height: 512

    Rectangle
    {
        id: ueKeypadWrapper
        antialiasing: true

        anchors.fill: parent

        ColumnLayout
        {
            id: ueKeypadLayoutMain
            antialiasing: true

            layoutDirection: Qt.LeftToRight
            spacing: 8

            anchors.fill: parent

            ColumnLayout
            {
                id: ueKeypadTitleLayout

                layoutDirection: Qt.LeftToRight

                Layout.fillWidth: true

                Layout.minimumHeight: 24
                Layout.preferredHeight: 24
                Layout.maximumHeight: 24

                Text
                {
                    Layout.fillWidth: true
                    Layout.fillHeight: true

                    text: qsTr("PIN ENTRY")
                    clip: true
                    font.bold: true
                    font.pointSize: 24
                    textFormat: Text.RichText
                    verticalAlignment: Text.AlignVCenter
                    horizontalAlignment: Text.AlignHCenter
                }   // Text
            }   // ColumnLayout

            GridLayout
            {
                id: ueKeypadNumbersLayout

                Layout.fillWidth: true
                Layout.fillHeight: true

                Layout.alignment: Qt.AlignHCenter|Qt.AlignVCenter

                layoutDirection: Qt.LeftToRight

                columnSpacing: 8
                rowSpacing: 8

                flow: GridLayout.LeftToRight

                columns: 3

                UeButton
                {
                    id: ueKeypadButton1

                    Layout.minimumHeight: 32
                    Layout.preferredHeight: 32
                    Layout.maximumHeight: 32

                    ueText: qsTr("1")
                }

                UeButton
                {
                    id: ueKeypadButton2

                    Layout.minimumHeight: 32
                    Layout.preferredHeight: 32
                    Layout.maximumHeight: 32

                    ueText: qsTr("2")
                }

                UeButton
                {
                    id: ueKeypadButton3

                    Layout.minimumHeight: 32
                    Layout.preferredHeight: 32
                    Layout.maximumHeight: 32

                    ueText: qsTr("3")
                }

                UeButton
                {
                    id: ueKeypadButton4

                    Layout.minimumHeight: 32
                    Layout.preferredHeight: 32
                    Layout.maximumHeight: 32

                    ueText: qsTr("4")
                }

                UeButton
                {
                    id: ueKeypadButton5

                    Layout.minimumHeight: 32
                    Layout.preferredHeight: 32
                    Layout.maximumHeight: 32

                    ueText: qsTr("5")
                }

                UeButton
                {
                    id: ueKeypadButton6

                    Layout.minimumHeight: 32
                    Layout.preferredHeight: 32
                    Layout.maximumHeight: 32

                    ueText: qsTr("6")
                }

                UeButton
                {
                    id: ueKeypadButton7

                    Layout.minimumHeight: 32
                    Layout.preferredHeight: 32
                    Layout.maximumHeight: 32

                    ueText: qsTr("7")
                }

                UeButton
                {
                    id: ueKeypadButton8

                    Layout.minimumHeight: 32
                    Layout.preferredHeight: 32
                    Layout.maximumHeight: 32

                    ueText: qsTr("8")
                }

                UeButton
                {
                    id: ueKeypadButton9

                    Layout.minimumHeight: 32
                    Layout.preferredHeight: 32
                    Layout.maximumHeight: 32

                    ueText: qsTr("9")
                }
            }   // GridLayout

            RowLayout
            {
                id: ueKeypadActionLayout

                Layout.fillWidth: true
                Layout.fillHeight: true

                Layout.alignment: Qt.AlignHCenter|Qt.AlignVCenter

                layoutDirection: Qt.LeftToRight

                spacing: 8

                UeButton
                {
                    id: ueKeypadButtonOk

                    ueText: qsTr("Ok")
                }   // UeButton

                UeButton
                {
                    id: ueKeypadButton0

                    ueText: qsTr("0")

                    Layout.minimumHeight: 32
                    Layout.preferredHeight: 32
                    Layout.maximumHeight: 32
                }   // UeButton

                UeButton
                {
                    id: ueKeypadButtonCancel

                    ueText: qsTr("Cancel")
                }   // UeButton
            }   // RowLayout
        }   // ColumnLayout
    }   // Rectangle
}   // Item

它使用自定义 QML Button,命名为 UeButton:

import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick 2.5

Button
{
    property string ueText

    id: ueButton

    text: ueText

    style: ButtonStyle
    {
        background: Rectangle
        {
            antialiasing: true
            smooth: true
            gradient: Gradient
            {
                GradientStop
                {
                    position: 0
                    color: "#ffffff"
                }   // GradientStop

                GradientStop
                {
                    position: 0.418
                    color: "#000000"
                }   // GradientStop
            }   // Gradient

            border.color: "steelblue"
            border.width: control.activeFocus?2:1
            radius: 4
        }   // background

        label: Text
        {
            color: "#ffffff"
            font.bold: true
            verticalAlignment: Text.AlignVCenter
            horizontalAlignment: Text.AlignHCenter
            font.pointSize: 16

            text: control.text
        }   // label
    }   // ButtonStyle
}   // ueButton

如果我在 QtCreator 的设计器工具中查看第一个代码,我会遇到以下情况:

为什么 Button 没有分布在 GridLayout 中?较低的 RowLayout 也是如此,其 Items(UeButton 类型的三个 Items)未在整个 RowLayout?[=23= 中居中和对齐]

Layout 的附加属性确保包含的 Item 大小正确 w.r.t。给定的约束。

Items可以拉伸填充可用的space(fillWidth/fillHeight),在一定值下强制不收缩(minimumWidth/minimumHeight) 或不放大超过某个其他值 (maximumWidth/maximumHeight)。您还可以强制 Item 占用多个 row/column (rowSpan/columnSpan) 并假定特定大小 (preferredWidth/preferredHeight 这意味着 minimum == maximum).

优先级为:

preferred <minimum/maximum <width/height

将 属性 设置到左侧会自动丢弃右侧的任何值。你可以很容易地理解这背后的原因。由于任何 Item 的大小都不能在这些值下缩小,因此该方案可能有点 "broken" by implicitWidth/implicitHeightfill 属性确保 Item 填充可用的 space,根据上面的约束:如果 fill 未定义,则 Item 不能根据它的约束。

现在,如果您希望 Button 保持它们的纵横比并仍然拉伸网格,您可以使用 中间 Item。在将 Layout 附加属性应用到外部 Item 时,Button 可以是 centerIn 它并且不受影响。

示例代码:

import QtQuick 2.5
import QtQuick.Window 2.2
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.4

Window {
    width: 200; height: 200; minimumHeight: 100; visible: true

    GridLayout {
        anchors.fill: parent
        rows: 3
        columns: 3

        Repeater {
            model: 9

            Item {
                Layout.fillWidth: true
                Layout.fillHeight: true

                Button { anchors.centerIn: parent; width: 32; height: 32; text: index + 1 }
            }
        }
    }
}

相反,如果您希望 Button 填充可用的 space,只需指定 fillWidth/fillHeight。由于没有设置其他布局约束(例如 minimum*maximum*),Button 正确地占据了所有可用的 space。这是重新访问上面的代码。正如预期的那样,widthheight 被简单地丢弃:

import QtQuick 2.5
import QtQuick.Window 2.2
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.4

Window {
    width: 200; height: 200; minimumHeight: 100; visible: true

    GridLayout {
        anchors.fill: parent
        rows: 3
        columns: 3

        Repeater {
            model: 9

            Button {width: 32; height: 32; text: index + 1;   // 32? NOPE!
                Layout.fillWidth: true; Layout.fillHeight: true
            }
        }
    }
}