Change Button function/style depending on StackView page



  • Hello,

    I'm developing an application with this layout:

    layout

    In main area there would be buttons to navigate to other pages and going to other page would change main area contents.
    Buttons in side area would execute different functions on each page and even change in style.

    My initial thought was to use StackView as a base and have the same layout on each page example of this:

    import QtQuick 2.9
    import QtQuick.Controls 2.2
    import QtQuick.Window 2.2
    
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        StackView {
            id: stackView
            anchors.fill: parent
            initialItem: Item {
                Rectangle {
                    id: mainArea
                    width: 480
                    height: 480
                    color: "orange"
                    Row {
                        Button {
                            text: "to page1"
                            onClicked: stackView.push(page1)
                        }
                        Button {
                            text: "to page2"
                            onClicked: stackView.push(page2)
                        }
                    }
                }
                Column {
                    anchors.left: mainArea.right
                    anchors.leftMargin: 20
                    Button {
                        text: "back"
                        onClicked: stackView.pop()
                    }
                    Button {
                        id: button
                        text: "button"
                        onClicked: console.log("button pressed")
                    }
                }
            }
        }
    
        Component {
            id: page1
            Item {
                Rectangle {
                    id: mainArea
                    width: 480
                    height: 480
                    color: "blue"
                    Row {
                        Button {
                            text: "to page1"
                            onClicked: stackView.push(page1)
                        }
                        Button {
                            text: "to page2"
                            onClicked: stackView.push(page2)
                        }
                    }
                }
                Column {
                    anchors.left: mainArea.right
                    anchors.leftMargin: 20
                    Button {
                        text: "back"
                        onClicked: stackView.pop()
                    }
                    Button {
                        id: button
                        text: "button"
                        onClicked: console.log("button pressed in page1")
                    }
                }
            }
        }
    
        Component {
            id: page2
            Item {
                Rectangle {
                    id: mainArea
                    width: 480
                    height: 480
                    color: "purple"
                    Row {
                        Button {
                            text: "to page1"
                            onClicked: stackView.push(page1)
                        }
                        Button {
                            text: "to page2"
                            onClicked: stackView.push(page2)
                        }
                    }
                }
                Column {
                    anchors.left: mainArea.right
                    anchors.leftMargin: 20
                    Button {
                        text: "back"
                        onClicked: stackView.pop()
                    }
                    Button {
                        id: button
                        text: "button"
                        onClicked: console.log("button pressed in page2")
                    }
                }
            }
        }
    }
    

    Problem with this approach is there would be a lot of components created unnecessarily.

    So I thought of another approach use StackView only in main area that way side area and top area would not be created on each page.
    example:

    import QtQuick 2.9
    import QtQuick.Controls 2.2
    import QtQuick.Window 2.2
    
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        StackView {
            id: stackView
            width: 480
            height: 480
            initialItem: Rectangle {
                color: "orange"
                Row {
                    Button {
                        text: "to page1"
                        onClicked: stackView.push(page1)
                    }
                    Button {
                        text: "to page2"
                        onClicked: stackView.push(page2)
                    }
                }
            }
        }
    
        Column {
            anchors.left: stackView.right
            anchors.leftMargin: 20
            Button {
                text: "back"
                onClicked: stackView.pop()
            }
            Button {
                id: button
                text: "button"
                onClicked: console.log("button pressed")
            }
        }
    
        Component {
            id: page1
            Rectangle {
                color: "blue"
            }
        }
    
        Component {
            id: page2
            Rectangle {
                color: "purple"
            }
        }
    }
    

    But with this approach I don't know how to change Button(id: button) function to i.e. console.log("button pressed in page1") in page1.

    If latter approach is the right way to go is there a way to change what button does in different page? preferably do it in the page component.
    Or maybe there is a better approach?



  • Hi @Eligijus,

    You can use States to deal with this easily i think
    http://doc.qt.io/qt-5/qml-qtquick-state.html



  • @LeLev Thanks for your suggestion but I can't figure out how to properly use states.
    In my second example when I enter page1 and press button it prints "button pressed" I want the same button to change page1 rectange color from blue to red. How would I achieve something like this with states?



  • @Eligijus said in Change Button function/style depending on StackView page:

    I want the same button to change page1 rectange color from blue to red

    This means page1 has states, let's say if (state = NORMAL color=blue) and (state = CRITICAL color = red)

    Its better to create Page1 and Page2 in new file:

    //Page1.qml

    import QtQuick 2.0
    Rectangle {
        id: back
        width: 200; height: 200
        state: "NORMAL"
        onStateChanged: console.log(state)
        states: [
            State {
                name: "NORMAL"
                PropertyChanges { target: back; color: "green"}
            },
            State {
                name: "CRITICAL"
                PropertyChanges { target: back; color: "red"}
            }
        ]
    }
    

    Then, in your 2nd exemple :

    Window {
        visible: true
        width: 640
        height: 480
    
        StackView {
            id: stackView
            width: 480
            height: 480
            initialItem: Rectangle {
                color: "orange"
                Row {
                    Button {
                        text: "to page1"
                        onClicked: stackView.push(page1)
                    }
                    Button {
                        text: "to page2"
                        onClicked: stackView.push(page2)
                    }
                }
            }
        }
    
        Column {
            anchors.left: stackView.right
            anchors.leftMargin: 20
            Button {
                text: "back"
                onClicked: stackView.pop()
            }
            Button {
                id: button
                text: "button"
                onClicked: {
                    console.log("button pressed")
                        stackView.currentItem.state = "CRITICAL" // 
                }
            }
        }
    
        Component {
            id: page1
           Page1{
           }
        }
     Component {
            id: page1
           Page2{
           }
        }
    
    }
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.