[SOLVED] Wrong button onClicked is fired when clicking on a disabled button using StackView



  • I am writing an application that uses StackView. I dynamically push pages onto the stack using an XmlListModel. On one of the pages, I needed to disable a button. However, when the user clicks on the disabled button, the onClicked event for a button in the same place on the initial page gets fired. It seems to be happening because of a reference to each plugin page from my main.qml. Any ideas on how to avoid this would be appreciated. I have included code from a small sample program that produces the same issue.

    MainPage.qml
    @
    import QtQuick 2.3
    import QtQuick.Controls 1.2
    import QtQuick.Layouts 1.1

    Item {
    id: root
    width: 400
    height: 400
    visible: true

    signal startSignal
    signal exitSignal
    
    Rectangle {
        id: background
        color: "white"
        anchors.fill: parent
        Row{
            Button {
                id: btnStart
                text: qsTr("Start")
                isDefault: false
                onClicked: mainPage.startSignal();
            }
            Button {
                id: btnExit
                text: "Exit"
                isDefault: false
                visible: true
                //this is fired when the SecondPage.btnExit is clicked while disabled
                onClicked: mainPage.exitSignal();
            }
        }
    }
    

    }
    @

    SecondPage.qml
    @
    import QtQuick 2.3
    import QtQuick.Controls 1.2
    import QtQuick.Layouts 1.1

    Item {
    id: root
    width: 400
    height: 400
    visible: true

    signal backSignal
    signal closeSignal
    
    Rectangle {
        id: background
        color: "white"
        anchors.fill: parent
        Row{
            Button {
                id: btnBack
                text: "Back"
                visible: true
                isDefault: false
                onClicked: secondPage.backSignal()
            }
            //button is disabled
            Button {
                id: btnExit
                text: "Exit"
                isDefault: false
                visible: true
                enabled: false
                onClicked: secondPage.closeSignal();
            }
        }
    }
    

    }
    @

    main.qml
    @
    import QtQuick 2.3
    import QtQuick.Controls 1.2
    import QtQuick.Layouts 1.1

    ApplicationWindow {
    id: win
    visible: true
    width: 400
    height: 400
    title: qsTr("Example")

    //reference to the second page to handle signals
    //the signal handlers in the real program are more complex
    SecondPage{
        id: secondPage
        onBackSignal: stackView.pop()
        onCloseSignal: Qt.quit()
    }
    
    //reference to the main page to handle signals
    //the signal handlers in the real program are more complex
    MainPage{
        id: mainPage
        onStartSignal: stackView.push(Qt.resolvedUrl("SecondPage.qml"))
        //this gets called when the secondPage.btnExit is clicked while disabled.
        //the onClicked for the mainPage.btnExit is fired.
        onExitSignal: Qt.quit()
    }
    Rectangle {
        id: rect1
        color: "white"
        anchors.fill: parent
    }
    //pages are added dynamically in the real program
    StackView {
        id: stackView
        objectName: "StackView"
        anchors.fill: parent
        focus: true
        initialItem: Qt.resolvedUrl("MainPage.qml")
    }
    

    }
    @



  • Hi,

    I don't think you need to create "SecondPage" and "MainPage" inside your main.qml. They are not necessary because you are using url to load the pages, and putting them there means, having three elements on top of each other:

    MainPage
    SecondPage
    StackView

    Als if you want to catch signals from items in a StackView its probably better to use a @Connections@ element in your main.qml. The way you are doing it now you are NOT catching the signals coming from the StackView.



  • Thank you for the reply. I am looking into Connections. What would I put for the target of the Connections element in the main.qml, if I removed the references to SecondPage and MainPage? All of the documentation I have found so far says that that is how you can access properties ,etc. from other qml files.



  • Hi,

    I'll try to explain things a bit better :-).

    The way you are working now, you have 2 MainPage.qml objects and 2 SecondPage.qml objects.

    The first pair of MainPage.qml and Second.qml are defined in your main.qml.

    The second pair, is created when you use your StackView.

    I am guessing this is not what you want.

    What you probably want to move between the first page and the second page and to quit the application if a certain button is pressed. Have a look at how it's done in documentation:

    http://qt-project.org/doc/qt-5/qml-qtquick-controls-stackview.html#details

    If you want to communicate with the stack view, you have two options:

    Although you are right in saying that you can access properties from other elements, what you are doing in MainPage.qml and SecondPage.qml is not necessarily the best idea.
    You are assuming that their will be elements called mainPage and secondPage defined somewhere. If those id's ever change your code will break. Also finding bugs will be very hard with this approach.



  • Okay, got it. That first option works. Thank you so much for the help!


Log in to reply
 

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