[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.1Item {
id: root
width: 400
height: 400
visible: truesignal 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.1Item {
id: root
width: 400
height: 400
visible: truesignal 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.1ApplicationWindow {
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
StackViewAls 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:
-
Define a set of common signals for both Pages and use @Connections {target: stackView.currentItem; onSignal: ...}@ in the stack view itself
-
Access the StackView directly using its attached property, use that to push and pop pages (http://qt-project.org/doc/qt-5/qml-qtquick-controls-stackview.html#supported-attached-properties).
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!