在 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 context 和 Repeater
工作方式相关的问题。来自后者的文档:
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)
}
显然,创建代码可以移动到其他任何地方,具体取决于您的需要。
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 context 和 Repeater
工作方式相关的问题。来自后者的文档:
Items instantiated by the
Repeater
are inserted, in order, as children of theRepeater
's parent. The insertion starts immediately after theRepeater
's position in its parent stacking list. This allows aRepeater
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)
}
显然,创建代码可以移动到其他任何地方,具体取决于您的需要。