首页 文章

项目未正确分布在GridLayout上

提问于
浏览
2

我有以下自定义QML Item ,它将代表一个密码输入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的Designer工具中查看第一个代码,我会遇到以下情况:

Problem Screenshot

为什么 Button 不会分布在 GridLayout 上?同样是低于 RowLayout ,其 Item (三个 Item 类型为 UeButton )没有居中并在整个 RowLayout 上对齐?

1 回答

  • 4

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

    可以拉伸 Item 以填充可用空间( fillWidth / fillHeight ),强制在某个值( minimumWidth / minimumHeight )下不缩小或不放大某个其他值( maximumWidth / maximumHeight ) . 您还可以强制 Item 占用多个行/列( rowSpan / columnSpan )并假设特定大小( preferredWidth / preferredHeight ,这意味着 minimum == maximum ) .

    优先顺序是:

    preferred < minimum / maximum < width / height

    向左设置属性会自动丢弃右侧的属性 . 您可以轻松理解这背后的原因 . 由于任何 Item 的大小在这些值下都不能缩小,因此该方案可能有点 implicitWidth/implicitHeight . 根据上述约束, fill 属性确保 Item 填充可用空间:如果未定义 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 填充可用空间,只需指定 fillWidth / fillHeight . 由于没有设置其他布局约束(例如 minimum*maximum* ), Button 正确占用了所有可用空间 . 以下是重新审视的代码 . 正如所料, 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
                }
            }
        }
    }
    

相关问题