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!