Home > Enterprise >  QML multiple window with keeping the state of all windows
QML multiple window with keeping the state of all windows

Time:11-16

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!

  • Related