我正在尝试在QML中实现以下GUI,并且无法理解如何正确浏览应用程序的不同页面。
主菜单中有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
}
}
}
}
}
答案 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
,信号,Connections
和Binding
元素来命名,或者在QML和/或C ++中实现一个界面来管理你的导航。
根据你的目标架构,尝试&学习让它变得完美!