qtqmlstackview

QML multiple window with keeping the state of all windows


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?


Solution

  • 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;
                            }
                        }
                    }
                }
            }
        }