首页 文章

QML中的页面导航

提问于
浏览
0

我正在尝试在QML中实现以下GUI,并且无法理解如何正确浏览应用程序的不同页面 .

enter image description here

主菜单中有3个按钮 . 当用户点击“演员”按钮时,UI切换到“演员视图”,用户可以在缩略图视图和列表视图之间切换 . 当用户点击其中一个演员时,UI切换到“演员详细信息”视图:具有“嵌套在其中”的电影视图的视图,其中列出了所有演员电影 .

我正在尝试使用StackView实现此功能 .

因此,当用户单击其中一个按钮时,我的StackView位于主菜单屏幕(main.qml)中,onClicked事件将正确的视图推送到堆栈 .

ActorsView.qml包含一个内部StackView(很可能是个坏主意)和两个在Thumb和Detail视图之间切换的按钮 . 这是通过将Thumb或Detail视图推送到本地堆栈来完成的 .

DetailView.qml和ThumbView.qml功能完全相同但看起来不同 . Here is where I ran into trouble . 我希望在Detail或Thumb视图中发生click事件时通知主视图 . 这样它(可以根据事件传递的信息)知道什么视图推入主堆栈 . 例如,当用户单击Actor1时,主菜单可以将'actor detail view for actor 1'推入堆栈 .

遗憾的是,我不知道如何“捕获”在父元素中嵌套组件中触发的事件 .

几周前我就开始玩QML和QT,并且很高兴听到我的方法完全错误,并且有更好的方法来实现我想要的 . 可悲的是,这是我发现的唯一可行的选择 .

main.qml

ApplicationWindow {
    title: qsTr("Hello World")
    width: 1280
    height: 720
    visible: true
    id: mainWindow

    Component{
        id: homeScreen
        Rectangle{
            height: 500
            width: 500
            color:"blue"
            anchors.centerIn: mainWindow

            Text {
                anchors.centerIn: parent
                text: qsTr("Home")
                font.pixelSize: 40
            }
        }
    }


    Component{
        id: actorsView
        ActorsView{
            view: stack
        }
    }


    Component{
        id: moviesView
        MoviesView{
            view: stack
        }
    }

    ColumnLayout{
        RowLayout{
            Layout.fillWidth: true


            Button{
                text: "Back"
                onClicked: stack.pop()

            }


            Button{
                text: "actor view"
                onClicked: stack.push(actorView)
            }

            Button{
                text: "movie view"
                onClicked: stack.push(moviesView)

            }

        }

        StackView {
            id: stack
            initialItem: homeScreen
            Layout.fillHeight: true
            Layout.fillWidth: true

        }

    }
}

ActorsView.qml

Item {
    property StackView view

    Component {
        id: actorDetailView
        DetailView {
            name: "actorDetailView"
            text: "Actor"
        }
    }

    Component {
        id: actorThumbView
        ThumbView {
            name: "actorThumbView"
            text: "Actor"
        }
    }

    ColumnLayout {

        RowLayout {

            Text {
                text: "Actor view"
                Layout.fillWidth: true
                horizontalAlignment: Text.AlignHCenter
            }

            Button {
                text: "Detail"
                onClicked: internalStack.push(actorDetailView)
            }
            Button {
                text: "Thumb"
                onClicked: internalStack.push(actorThumbView)
            }

            Button {
                text: "back"
                onClicked: internalStack.pop()
            }

            Button {
                text: "depth: " + internalStack.depth

            }
        }

        StackView {
            id: internalStack
            initialItem: {
                console.log(internalStack.depth)
                internalStack.initialItem = actorThumbView
            }
            Layout.fillHeight: true
            Layout.fillWidth: true
        }
    }
}

ThumbView.qml

Item {
    property string name: "thumbView"
    property string text
    property int counter: 0
    id:thumbView
    signal thumbPressed (string pressedName)

    GridLayout {
        columnSpacing: 10
        rowSpacing: 10
        width: parent.width

        Repeater {
            model: 16
            Rectangle {

                width: 200
                height: 300
                color: "grey"
                Text {
                    id: lable
                    text: text
                    anchors.centerIn: parent
                }

                MouseArea {
                    anchors.fill: parent
                    onClicked: {
                        var tag = lable.text
                        console.log("You have clicked " + tag)

                        thumbView.thumbPressed(tag)
                    }
                }

                Component.onCompleted: {
                    counter = counter + 1
                    lable.text = text + " " + counter
                }
            }
        }
    }
}

1 回答

  • 2

    那个's actually a common approach to structure a QML application, so no it'并不全坏!嵌套StackViews是一种管理页面子内容的强大方法,但肯定会在您的应用程序结构中添加一个级别 . 通过创建自己的 Page 项目,根据需要重新定义导航和交互,可以更轻松 .

    在嵌套组件中处理信号的方法有很多种 . 最简单的方法:在层次结构中调用标识的项目 . QML中的本地和父元素可以直接从它们的 id 访问,即使它们不在同一个QML文件中 . 哪个允许这当然具有诱导页面或组件与应用程序其余部分之间耦合的缺点 .

    ApplicationWindow {
        id: mainWindow
    
        function pushPage(page) {
            stack.push(page)
        }
        function showActor(id) {
            ...
        }
    
        // ...
    }
    

    在你的页面中......

    MouseArea {
        onClicked: {
            mainWindow.showActor(index)
        }
    }
    

    要实现更模块化的功能,您可以依赖StackView currentItem ,signal,ConnectionsBinding元素来命名,或者在QML和/或C中实现一个界面来管理您的导航 .

    根据你的目标架构,肯定有很多可能性,尝试和学习使它变得完美!

相关问题