我正在尝试在QML中实现以下GUI,并且无法理解如何正确浏览应用程序的不同页面 .
主菜单中有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 回答
那个's actually a common approach to structure a QML application, so no it'并不全坏!嵌套StackViews是一种管理页面子内容的强大方法,但肯定会在您的应用程序结构中添加一个级别 . 通过创建自己的
Page
项目,根据需要重新定义导航和交互,可以更轻松 .在嵌套组件中处理信号的方法有很多种 . 最简单的方法:在层次结构中调用标识的项目 . QML中的本地和父元素可以直接从它们的
id
访问,即使它们不在同一个QML文件中 . 哪个允许这当然具有诱导页面或组件与应用程序其余部分之间耦合的缺点 .在你的页面中......
要实现更模块化的功能,您可以依赖StackView
currentItem
,signal,Connections和Binding元素来命名,或者在QML和/或C中实现一个界面来管理您的导航 .根据你的目标架构,肯定有很多可能性,尝试和学习使它变得完美!