QML - 嵌套 StackView 的递归路径

问题描述 投票:0回答:1

我有一个包含嵌套 StackView 的 QML 代码。我正在尝试建立一个动态且自动的“路径”系统,该系统将在屏幕顶部显示到达当前视图(包括子 StackView)的路径。例如,使用以下代码,我们将看到显示:

Path: Home > Module 1 > Sub-Module 3 > Data Page

理想情况下,我还希望单击路径中的名称可以将我们带到该页面,此外还有一个可向后导航一页的后退按钮。因此,将

objectName
属性添加到动态更新列表的解决方案并不是真正可行,因为它不太灵活。

这是我当前的代码,其中路径仅适用于第一个 StackView。我怎样才能添加这个功能?

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15

ApplicationWindow {
    visible: true
    width: 800
    height: 600
    title: "StackView With Dynamic Path"

    ColumnLayout {
        anchors.fill: parent

        RowLayout {
            id: pathBar
            spacing: 5
            Layout.fillWidth: true
            Text {
                text: "Path :"
                font.bold: true
            }
            Repeater {
                model: stackPath
                Row {
                    spacing: 5
                    Text {
                        text: modelData
                    }
                    Text {
                        visible: index < stackPath.count - 1
                        text: ">"
                    }
                }
            }
        }

        // StackView principal
        StackView {
            id: mainStackView
            Layout.fillWidth: true
            Layout.fillHeight: true
            initialItem: homeComponent
            clip: true

            Component {
                id: homeComponent
                Page {
                    objectName: "Home"
                    Rectangle {
                        color: "lightblue"
                        anchors.fill: parent
                        Text {
                            anchors.centerIn: parent
                            text: "Homepage"
                        }
                        Button {
                            text: "Go to Module 1"
                            anchors.bottom: parent.bottom
                            anchors.horizontalCenter: parent.horizontalCenter
                            onClicked: mainStackView.push(module1Component)
                        }
                    }
                }
            }

            Component {
                id: module1Component
                Page {
                    objectName: "Module 1"
                    StackView {
                        id: module1StackView
                        anchors.fill: parent
                        initialItem: subModuleComponent
                        Connections {
                            target: module1StackView
                            onCurrentItemChanged: updatePath()
                            onPush: updatePath()
                            onPop: updatePath()
                        }

                        Component {
                            id: subModuleComponent
                            Page {
                                objectName: "Sub-Module 3"
                                Rectangle {
                                    color: "lightgreen"
                                    anchors.fill: parent
                                    Text {
                                        anchors.centerIn: parent
                                        text: "Sub-Module 3"
                                    }
                                    Button {
                                        text: "Go to Data Page"
                                        anchors.bottom: parent.bottom
                                        anchors.horizontalCenter: parent.horizontalCenter
                                        onClicked: module1StackView.push(dataPageComponent)
                                    }
                                    Button {
                                        text: "Back"
                                        anchors.bottom: parent.bottom
                                        anchors.left: parent.left
                                        onClicked: module1StackView.pop()
                                    }
                                }
                            }
                        }

                        Component {
                            id: dataPageComponent
                            Page {
                                objectName: "Data Page"
                                Rectangle {
                                    color: "lightcoral"
                                    anchors.fill: parent
                                    Text {
                                        anchors.centerIn: parent
                                        text: "Data Page"
                                    }
                                    Button {
                                        text: "Back"
                                        anchors.bottom: parent.bottom
                                        anchors.left: parent.left
                                        onClicked: module1StackView.pop()
                                    }
                                }
                            }
                        }
                    }
                    Button {
                        text: "Back"
                        anchors.bottom: parent.bottom
                        anchors.left: parent.left
                        onClicked: mainStackView.pop()
                    }
                }
            }
        }
    }

    ListModel {
        id: stackPath
    }

    function updatePath() {
        stackPath.clear()
        buildPath(mainStackView, "")
    }

    function buildPath(stackView, currentPath) {
        for (var i = 0; i < stackView.depth; i++) {
            var currentItem = stackView.get(i)
            currentPath += currentItem.objectName
            stackPath.append({ name: currentItem.objectName })
            var childStackView = currentItem.children.find(function(item) {
                return item instanceof StackView
            })
            if (childStackView && childStackView.currentItem) {
                buildPath(childStackView, currentPath + " > ")
            }
        }
    }

    Connections {
        target: mainStackView
        onCurrentItemChanged: updatePath()
        onPush: updatePath()
        onPop: updatePath()
    }

    Component.onCompleted: updatePath()
}
qt recursion qml qt6
1个回答
0
投票

似乎你有一个可行的解决方案,但是,我认为我们可以用一个标签来做到这一点。以下内容有效,因为从推送/弹出操作对

stackView.depth
的更改将导致重新评估文本属性。另外,您使用 objectName,我建议您改用 Page.title :

Label {
    text: {
        let titles = [ ];
        for (let i = 0; i < stackView.depth; i++)
            titles.push(stackView.get(i).title);
        return titles.join( " > " );
    }
}

您可以在线尝试!

© www.soinside.com 2019 - 2024. All rights reserved.