QML中的页面导航

时间:2017-03-12 19:12:48

标签: qt qml

我正在尝试在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功能完全相同但看起来不同。 这是我遇到麻烦的地方。我希望在Detail或Thumb视图中发生click事件时通知主视图。这样它(可以根据事件传递的信息)知道什么视图推入主堆栈。例如,当用户点击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

        }

    }
}

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 个答案:

答案 0 :(得分:2)

这实际上是构建QML应用程序的常用方法,所以不是不是全部都不好!嵌套StackViews是一种管理页面子内容的强大方法,但肯定会在您的应用程序结构中添加一个级别。通过创建自己的Page项目,根据需要重新定义导航和交互,可以更轻松。

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

ApplicationWindow {
    id: mainWindow

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

    // ...
}

在您的页面中简单地......

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

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

根据你的目标架构,尝试&学习让它变得完美!