QML / Qt Quick 奇怪的布局

QML / Qt Quick weird layout

我正在使用 QML (Qt Quick) 来设置应用程序的 GUI,但我遇到了奇怪的行为。

这是我最初的一段代码:

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3

Rectangle {
    id: rectangle1
    color: palette.grey

    ColumnLayout
    {
        id: columnLayout1

        Label
        {
            id: label1
            text: qsTr("Target")
            font.pointSize: 22
        }

        ProgressBar
        {
            id: progressBar1
            value: 0.5
        }
    } }

... 给出布局:

然后我锚定中心:

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3

Rectangle
{
    id: rectangle1
    color: palette.grey

    ColumnLayout
    {
        id: columnLayout1
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.verticalCenter: parent.verticalCenter

        Label
        {
            id: label1
            text: qsTr("Target")
            font.pointSize: 22
        }

        ProgressBar
        {
            id: progressBar1
            value: 0.5
        }
    }
}

没问题,我得到:

现在当我旋转滑块时出现问题:

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3

Rectangle
{
    id: rectangle1
    color: palette.grey

    ColumnLayout
    {
        id: columnLayout1
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.verticalCenter: parent.verticalCenter

        Label
        {
            id: label1
            text: qsTr("Target")
            font.pointSize: 22
        }

        ProgressBar
        {
            id: progressBar1
            rotation: 90
            value: 0.5
        }
    }
}

在这里我期待 Qt 旋转滑块并使用旋转的滑块来计算布局,但事实并非如此。实际上布局似乎是在滑块未旋转的情况下计算的,然后只有滑块旋转。这最终得到一个不再是列的布局:

这看起来有点问题,不是吗?还是我做错了什么?

现在当我将滑块包裹在一个项目中时出现另一个问题(我实际上是在玩项目以查看是否可以找到解决方法):

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3

Rectangle
{
    id: rectangle1
    color: palette.grey

    ColumnLayout
    {
        id: columnLayout1
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.verticalCenter: parent.verticalCenter

        Label
        {
            id: label1
            text: qsTr("Target")
            font.pointSize: 22
        }

        Item
        {
            ProgressBar
            {
                id: progressBar1
                value: 0.5
            }
        }
    }
}

在这种情况下,我得到的是标签上方的滑块(尽管它在代码中定义在它之后):

这对我来说也很奇怪...有人知道我做错了什么吗?

请注意,屏幕截图是从 Designer 捕获的,但 运行 该程序会导致完全相同的问题。

亲切的问候,

安托万·伦纽特。

Now things go wrong when I rotate the slider

旋转不影响 widthheight 属性。您可以通过将以下行添加到 ProgressBar:

来检查这一点
onWidthChanged: print("width", width)
onHeightChanged: print("height", height)

如果 ProgressBar 有一个 orientation 属性,就像在 Qt Quick Controls 1 中一样,您可以使用它来代替 rotation。旋转栏时也不能简单地翻转 widthheight,因为布局使用 implicitWidthimplicitHeight,而不是 widthheight:

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3

import QtQuick.Controls 2.1

ApplicationWindow {
    width: 400
    height: 300
    visible: true

    ColumnLayout {
        id: columnLayout1
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.verticalCenter: parent.verticalCenter

        Label {
            id: label1
            text: qsTr("Target")
            font.pointSize: 22
        }

        ProgressBar {
            id: progressBar1
            rotation: 90
            width: implicitHeight
            height: implicitWidth
            value: 0.5
        }
    }
}

您可以自己计算 implicitWidthimplicitHeight,但这并不好。

Now another problem occurs when I wrap the slider in an Item

你走在正确的轨道上。正如 this 回答中提到的,您需要给 Item 一个尺寸。您可以这样做:

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3

import QtQuick.Controls 2.1

ApplicationWindow {
    width: 400
    height: 300
    visible: true

    ColumnLayout {
        id: columnLayout1
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.verticalCenter: parent.verticalCenter

        Label {
            id: label1
            text: qsTr("Target")
            font.pointSize: 22
        }

        Item {
            implicitWidth: progressBar1.implicitHeight
            implicitHeight: progressBar1.implicitWidth

            ProgressBar {
                id: progressBar1
                rotation: 90
                value: 0.5
            }
        }
    }
}

请注意,进度条的位置仍然不正确。那是因为default transform origin for items is in the centre。将其设置为 BottomLeft 有效:

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3

import QtQuick.Controls 2.1

ApplicationWindow {
    width: 400
    height: 300
    visible: true

    ColumnLayout {
        id: columnLayout1
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.verticalCenter: parent.verticalCenter

        Label {
            id: label1
            text: qsTr("Target")
            font.pointSize: 22
        }

        Item {
            implicitWidth: progressBar1.implicitHeight
            implicitHeight: progressBar1.implicitWidth + progressBar1.implicitHeight

            ProgressBar {
                id: progressBar1
                rotation: 90
                transformOrigin: Item.BottomLeft
                value: 0.5
            }
        }
    }
}

请注意,您还必须将条形的 implicitHeight 添加到 ItemimplicitHeight,以说明我们所做的变换原点更改。

我强烈建议您在 bugreports.qt.io 上创建方向 属性 的建议。 :)