Qt QML中的页面导航
我试图在QML中实现以下GUI,但在理解如何正确浏览应用程序的不同页面时遇到了困难Qt QML中的页面导航,qt,qml,Qt,Qml,我试图在QML中实现以下GUI,但在理解如何正确浏览应用程序的不同页面时遇到了困难 ApplicationWindow { id: mainWindow function pushPage(page) { stack.push(page) } function showActor(id) { ... } // ... } 主菜单中有3个按钮。当用户单击“actor”按钮时,UI将切换到“actor视图”,用户
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++中实现一个接口来管理导航。
根据你的目标架构,肯定有很多可能性,尝试和学习会让它变得完美 谢谢大家!!我正在使用您建议的方法,在根目录中声明导航函数,并从层次结构中的项目中调用它们。