I want to develop a qml application that starts with the main window and three buttons are available in the main window. By pressing each button a new page(Layout) should show up, but after returning to the main window, the state of the previous page should not change. I have tried ListView but it did not work, because it destroys the Item after pop(). Here is my Code(PagesOne.qml is a sample for three pages that I want to open):
main.qml
ApplicationWindow {
id: root
visible: true
width: 8 * Screen.width / 10
height: 8 * Screen.height / 10
color: "#154c79"
// Keep the window on the given x,y on starting
Component.onCompleted: {
x: Screen.width / 10
y: Screen.height / 10
}
minimumWidth: 700
minimumHeight: 400
// Current Working Layout
Component {
id: pageOne
PageOne{}
}
// Empty Layout
Component {
id: pageTwo
PageTwo{}
}
// Empty Layout
Component {
id: pageThree
PageThree{}
}
property variant items: [pageOne.createObject(), pageTwo.createObject(), pageThree.createObject()]
StackView {
id: stack
anchors.fill: parent
// initialItem: pageOne
Component.onCompleted: {
stack.push(items[2], {"destroyOnPop": false})
stack.push(items[1], {"destroyOnPop": false})
stack.push(items[0], {"destroyOnPop": false})
}
}
// change layout on call
function load_layout(layout){
console.log("#############", stack.depth, "#############")
switch (layout){
case 'one':
stack.pop(0, {"destroyOnPop": false})
break;
case 'two':
stack.pop(1, {"destroyOnPop": false})
break;
case 'three':
stack.pop(2, {"destroyOnPop": false})
break;
default:
stack.pop(0, {"destroyOnPop": false})
}
}
}
PageOne.qml:
Item{
id: root
// anchors.fill: parent
// Empty rect
Rectangle{
color: "#03fc88"
anchors.fill: parent
TextField {
anchors.right: parent.right
anchors.top: parent.top
width: 120
height: 60
placeholderText: qsTr("Enter: ")
}
Label{
anchors.centerIn: parent
text: "Page two"
}
// return button
RoundButton {
id: btnBack
text: "\u003C"
onClicked: {
if(text === "\u003C"){
load_layout('one')
}
}
}
}
}
Is there any suggestion that helps me?
CodePudding user response:
A simple example:
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.0
Window {
height: 800
width: 600
visible: true
title: qsTr("Stack test")
ColumnLayout {
anchors.fill: parent
spacing: 0
StackView {
id: stack
Layout.fillHeight: true
Layout.fillWidth: true
initialItem: screen1
Rectangle {
id: screen1
color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
}
Rectangle {
id: screen2
color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
}
Rectangle {
id: screen3
color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
}
}
RowLayout {
id: bar
Layout.fillWidth: true
Layout.preferredHeight: 50
spacing: 0
Button {
Layout.preferredWidth: 300
Layout.preferredHeight: 50
text: "Change color"
onClicked: {
stack.currentItem.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1);
}
}
Button {
Layout.preferredWidth: 300
Layout.preferredHeight: 50
text: "Next"
onClicked: {
switch(stack.currentItem)
{
case screen1:
stack.replace(screen2)
break;
case screen2:
stack.replace(screen3)
break;
case screen3:
stack.replace(screen1)
break;
}
}
}
}
}
}
CodePudding user response:
Because, in your main page, you use Component, by definition, QML can create and destroy as many instances of the page corresponding to push/pull on the stack. So, the feature you described is as per design.
If you want to maintain an instance that is persistent, do not use Component. Instead, declare an instance of the pages but keep them invisible.
In the following example, I declare Pages each with a different TextField. As you switch between the pages, you can resume editing the TextField on that page exactly where you left it.
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Page {
StackView {
id: stackView
anchors.fill: parent
initialItem: "MenuPage.qml"
}
PageOne {
id: pageOne
visible: false
}
PageTwo {
id: pageTwo
visible: false
}
PageThree {
id: pageThree
visible: false
}
}
// MenuPage.qml
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Page {
header: Label { text: "MainPage" }
ColumnLayout {
Button {
text: qsTr("Page One")
onClicked: stackView.push(pageOne)
}
Button {
text: qsTr("Page Two")
onClicked: stackView.push(pageTwo)
}
Button {
text: qsTr("Page Three")
onClicked: stackView.push(pageThree)
}
}
}
// PageOne.qml
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Page {
header: Label { text: "Page One" }
ColumnLayout {
TextField {
text: "sheep"
}
Button {
text: qsTr("Back")
onClicked: stackView.pop()
}
}
}
// PageTwo.qml
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Page {
header: Label { text: "Page Two" }
ColumnLayout {
TextField {
text: "magic"
}
Button {
text: qsTr("Back")
onClicked: stackView.pop()
}
}
}
// PageThree.qml
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Page {
header: Label { text: "Page Three" }
ColumnLayout {
TextField {
text: "xyzzy"
}
Button {
text: qsTr("Back")
onClicked: stackView.pop()
}
}
}
You can Try it Online!
