QML - GridLayout - 无法使用它使页面居中

QML - GridLayout - unable to center a page using it

我是 Qt 和 QML 的新手,在尝试学习它们时遇到了以下问题,我不确定它们出现的原因。

我有一个按钮,当我按下它时,屏幕上会显示一个新的紫色矩形。我试图将它定位在屏幕的中央,或者换句话说要填满整个屏幕,但出于某种原因,我不能这样做,而且它总是从第 2 项的开头开始,而不是从第 2 项的开头开始屏幕的开头。此外,它将放置在项目 1 和项目 3 下,而不是覆盖它们。

我的代码:

import QtQuick 2.14
import QtQuick.Window 2.14
import QtQuick.Layouts 1.14
import QtQuick.Controls 2.12

Window {
    id: mainD
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    GridLayout {
        id : grid
        anchors.fill: parent
        rows    : 12
        columns : 20
        property double colMulti : grid.width / grid.columns
        property double rowMulti : grid.height / grid.rows
        function prefWidth(item){
            return colMulti * item.Layout.columnSpan
        }
        function prefHeight(item){
            return rowMulti * item.Layout.rowSpan
        }
        Rectangle {
            id: id1
            color : 'red'
            Layout.column: 0
            Layout.rowSpan: 10
            Layout.columnSpan: 2
            Layout.preferredWidth  : grid.prefWidth(this)
            Layout.preferredHeight : grid.prefHeight(this)
        }
        Rectangle {
            id: id2
            color : 'green'
            Layout.column: 2
            Layout.rowSpan: 10
            Layout.columnSpan: 18
            Layout.preferredWidth  : grid.prefWidth(this)
            Layout.preferredHeight : grid.prefHeight(this)
            Button{
                width: 100
                height: 100
                anchors.horizontalCenter: parent.horizontalCenter
                anchors.verticalCenter: parent.verticalCenter
                onClicked: {
                    id2.state = "STATE_1"
                }
            }

            StackView{
                id: st
                width: parent.width
                height: parent.height + 100
                
                anchors.horizontalCenter: grid.parent.horizontalCenter
                anchors.verticalCenter: grid.parent.verticalCenter

                visible: false
                Rectangle{
                    anchors.fill: parent
                    color: "purple"
                    opacity: 0.7
                    Button{
                        width: 100
                        height: 100
                        onClicked: {
                            id2.state = "STATE_2"
                        }
                    }
                }
            }

            states: [
                State{
                    name: "STATE_1"
                    PropertyChanges {
                        target: st;
                        visible: true
                    }
                },
                State{
                    name: "STATE_2"
                    PropertyChanges {
                        target: st;
                        visible: false
                    }
                }
            ]
        }
        Rectangle {
            id: id3
            color : 'blue'
            Layout.column: 18
            Layout.rowSpan: 10
            Layout.columnSpan: 2
            Layout.preferredWidth  : grid.prefWidth(this)
            Layout.preferredHeight : grid.prefHeight(this)
        }
    }
}

任何人都可以向我解释我做错了什么吗?

紫色矩形是 StackView 对象的初始项,其 ID 为“st”。它最初是隐藏的。 “id2”是“st”的视觉父级。 “st”的坐标是相对于其视觉父级的。您将其宽度设置为其父项的宽度,将高度设置为父项的高度 + 100,因此其 (0,0) 坐标转到父项的 (0,0)。您应该从文档中阅读更多内容:Visual Parent in Qt Quick.

如果你想用紫色矩形填充整个屏幕并将其放置在其他视觉项目的顶部,你可以通过将“st”从“网格”中移出并将其放置在同一水平面上来实现。现在“grid”和“st”都是“mainD”的子级,并且因为 StackView 在“grid”下面,所以你不需要使用 z 值,但是当“st”变得可见时,它会在“grid”之上呈现.

Window {
    id: mainD
    ...

    GridLayout {
        id : grid
        ...
    }
    StackView{
        id: st
        width: parent.width
        height: parent.height// + 100

        //anchors.horizontalCenter: grid.parent.horizontalCenter
        //anchors.verticalCenter: grid.parent.verticalCenter

        visible: false
        Rectangle{
            anchors.fill: parent
            color: "purple"
            opacity: 0.7
            Button{
                width: 100
                height: 100
                onClicked: {
                    id2.state = "STATE_2"
                }
            }
        }
    }
}

我推荐免费 Qt5 Cadaques 书中的 Positioning elements 章以供进一步阅读。

I'm having a button, at the moment when I'm pressing it will display a new purple Rectangle over the screen. I am trying to position it at the center of the screen, or in other words to fill the whole screen

正如@talamaki 提到的,如果你想让紫色填充整个背景,最好将它作为主要项目的子项,而不是让它成为网格的一部分,然后让它扩展分配的 space在网格内。

but for some reason, I can't do that, and It's always going to start from the beginning of Item 2 instead of the beginning of the screen.

这是因为网格的工作原理。把它想象成一个棋盘,第 1 项已经占据了前两列,所以第 2 项将从第 3 列开始,第 2 项的任何子项从第 2 项的坐标系开始。你可以让它超出它的起点但我认为将背景放在根项目上会更干净。

Also, it's going to be placed under Item 1 and Item 3 instead to overlay them.

要让紫色位于 1 和 3 下方,必须先绘制它(在 QML 中应该先绘制)。如果您不希望按钮受到影响,您应该将它放在 QML 文件中的 GridLayout 下方,以便它最后绘制在它上面。将所有这些放在一起会是这样的:

import QtQuick 2.14
import QtQuick.Window 2.14
import QtQuick.Layouts 1.14
import QtQuick.Controls 2.12

Window {
    id: mainD
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
        
    Rectangle{
        id: background
        anchors.fill: parent
        color: "purple"
        opacity: 0.7
        visible: false
    }

    GridLayout {
        id : grid
        anchors.fill: parent
        rows    : 12
        columns : 20
        property double colMulti : grid.width / grid.columns
        property double rowMulti : grid.height / grid.rows
        function prefWidth(item){
            return colMulti * item.Layout.columnSpan
        }
        function prefHeight(item){
            return rowMulti * item.Layout.rowSpan
        }
        
        Rectangle {
            id: id1
            color : 'red'
            Layout.column: 0
            Layout.rowSpan: 10
            Layout.columnSpan: 2
            Layout.preferredWidth  : grid.prefWidth(this)
            Layout.preferredHeight : grid.prefHeight(this)
        }
        Rectangle {
            id: id2
            color : 'green'
            Layout.column: 2
            Layout.rowSpan: 10
            Layout.columnSpan: 16
            Layout.preferredWidth  : grid.prefWidth(this)
            Layout.preferredHeight : grid.prefHeight(this)
        }
        Rectangle {
            id: id3
            color : 'blue'
            Layout.column: 18
            Layout.rowSpan: 10
            Layout.columnSpan: 2
            Layout.preferredWidth  : grid.prefWidth(this)
            Layout.preferredHeight : grid.prefHeight(this)
        }
    }

    Button{
        width: 100
        height: 100
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.verticalCenter: parent.verticalCenter
        onClicked: {
            background.visible = !background.visible
        }
    }
}

根据你的问题,我不清楚你是想让项目 2 消失,让它的颜色与背景混合,还是让它在你单击按钮时保持在顶部。