Qt QML中的页面导航

Qt QML中的页面导航,qt,qml,Qt,Qml,我试图在QML中实现以下GUI,但在理解如何正确浏览应用程序的不同页面时遇到了困难 ApplicationWindow { id: mainWindow function pushPage(page) { stack.push(page) } function showActor(id) { ... } // ... } 主菜单中有3个按钮。当用户单击“actor”按钮时,UI将切换到“actor视图”,用户

我试图在QML中实现以下GUI,但在理解如何正确浏览应用程序的不同页面时遇到了困难

ApplicationWindow {
    id: mainWindow

    function pushPage(page) {
        stack.push(page)
    }
    function showActor(id) {
        ...
    }

    // ...
}

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

我正在尝试使用

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

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

DetailView.qml和ThumbView.qml的功能完全相同,但看起来不同这就是我遇到麻烦的地方。我希望在细节视图或拇指视图中发生单击事件时通知主视图。这样它就可以(基于传递的事件信息)知道将什么视图推送到主堆栈上。例如,当用户单击Actor1时,主菜单可以将“actor 1的actor详细视图”推到堆栈上

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

就在几周前,我开始使用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

        }

    }
}
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
        }
    }
}
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
                }
            }
        }
    }
}
ActorView.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

        }

    }
}
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
        }
    }
}
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
                }
            }
        }
    }
}
拇指视图.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

        }

    }
}
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
        }
    }
}
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
                }
            }
        }
    }
}

这实际上是构造QML应用程序的常用方法,所以不,这并不全是坏事!嵌套的StackView是管理页面子内容的一种强大方式,但肯定会在应用程序结构中添加一个级别。通过创建您自己的
页面
项目,并根据您的意愿重新定义导航和交互,您可以更轻松地完成此任务

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

ApplicationWindow {
    id: mainWindow

    function pushPage(page) {
        stack.push(page)
    }
    function showActor(id) {
        ...
    }

    // ...
}
在您的页面中,只需

MouseArea {
    onClicked: {
        mainWindow.showActor(index)
    }
}
< >为了实现更模块化的功能,您可以依赖StaveVIEW、代码> CurrimeTe>、代码>、信号和元素来命名,或者在QML和/或C++中实现一个接口来管理导航。
根据你的目标架构,肯定有很多可能性,尝试和学习会让它变得完美

谢谢大家!!我正在使用您建议的方法,在根目录中声明导航函数,并从层次结构中的项目中调用它们。