在 QML 中构建 TabBar - Loader 不显示所有矩形

Building TabBar in QML - Loader doesn't show all the Rectangles

import QtQuick 2.4
import QtQuick.Window 2.2

Window
{
    visible: true
    height: 500
    width: 500

    property VisualItemModel contentToBeShownOnTabClick : visualItemModelDemo
    property variant tabLabels                    : ["Navigation", "Payload", "System Control"]

    VisualItemModel
    {
        id: visualItemModelDemo

        Rectangle
        {
            id: navigationTab
            color: "green"
            height: 200
            width: 200
        }
        Rectangle
        {
            id: navigationTab1
            color: "darkgreen"
            height: 200
            width: 200
        }
        Rectangle
        {
            id: navigationTab2
            color: "lightgreen"
            height: 200
            width: 200
        }
    }

    MainForm
    {
        Component
        {
            id: tabsOnBottomComponent
            Repeater
            {
                model:   tabLabels
                // The Tabs
                Rectangle
                {
                    id:             tabsOnBottom
                    // This anchoring places the tabs on the outer top of the parent rectangle.
                    anchors.top:    parent.bottom
                    anchors.topMargin: 180
                    color:          "lightsteelblue"
                    border.color:   "steelblue"
                    border.width:   2
                    implicitWidth:  Math.max ((labelTabsBottom.width + 4), 80)
                    implicitHeight: 20
                    radius:         2
                    // Tabs Text/Label
                    Text
                    {
                        id:                 labelTabsBottom
                        anchors.centerIn:   parent
                        color:              "white"
                        rotation:           0
                        // With reference to mode: tabLabels
                        text:               modelData
                        font.pointSize:     11
                    }

                    MouseArea
                    {
                        anchors.fill: parent
                        onClicked:    bottomTabClicked (index);
                    }
                }
            }
        }


        Rectangle
        {
            // The things which get displayed on clicking of a tab will be shown in this rectangle.
            id:           areaForTabContents
            border.color: "black"
            border.width: 10
            height:       parent.height
            width :       parent.width
            color :       "pink"

            // These are the tabs displayed in one row - horizontally.
            Row
            {
                id:      horizontalTabs

                Loader
                {
                    anchors.fill: parent
                    sourceComponent: tabsOnBottomComponent
                }
            }
        }

        anchors.fill: parent
    }
}

显示如下:

而我想让它看到 3 个并排的矩形。

Loader 不是透明类型 w.r.t。包含类型,在本例中为 Row。我认为这是与 creation contextRepeater 工作方式相关的问题。来自后者的文档:

Items instantiated by the Repeater are inserted, in order, as children of the Repeater's parent. The insertion starts immediately after the Repeater's position in its parent stacking list. This allows a Repeater to be used inside a layout.

Rectangle 确实添加到 Loader 的父级,它们 叠加 - Loader 不提供定位策略 - 然后将它们添加到 Row,结果只有一个 Item(最后一个)可见。

您可以使用几种不同的方法来解决该问题,具体取决于您是否要维护的属性。我会摆脱 Component 中的锚定并将其移动到包含 Row 中。 Component 中过于具体的锚定在整个(不是那么小的)项目中实例化和使用时可能会让人头疼。

作为第一种方法,您可以将 Repeater 重新设置为 Row,即您可以将代码重写为:

Row
{
    id: horizontalTabs

    Loader
    {
        sourceComponent: tabsOnBottomComponent
        onLoaded: item.parent = horizontalTabs
    }
}

然而,由于 Component 锚定引用不再按预期工作,这将导致警告。

如果您仍想保持 Component 中定义的锚定并卸载创建,您可以采用动态方式(如果语义适合您的用例),即你可以使用 createObject。这样您就可以完全避免 Loader 和相关问题。例如,您可以在 Row 完成创建后创建 Repeater

Row
{
    id: horizontalTabs
    Component.onCompleted: tabsOnBottomComponent.createObject(horizontalTabs)
}

显然,创建代码可以移动到其他任何地方,具体取决于您的需要。