How to remove StackView Transitions
-
I have a QtQuick/PySide2 application (Qt 5.15) and want to push 2 page on a
StackView
without seeing transitions.
But I getQML StackView: cannot push while already in the process of completing a push
. Having the default transitions this code works:// main.qml Window { width: 640 height: 480 visible: true title: qsTr("Hello World") StackView { id: stackview onDepthChanged: console.debug(`Depth: ${depth}`) initialItem: AutoPushPage {} pushEnter: null pushExit: null } }
// AutoPushPage.qml Page { id: root readonly property string mypage: Qt.resolvedUrl("MyPage.qml") readonly property bool isDeviceConnected: true StackView.onActivated: { if (root.isDeviceConnected) { stackview.push(mypage, {title: "automatically pushed by onActivated"}) } } }
//MyPage.qml Page { id: root readonly property string autoPushPage: Qt.resolvedUrl("AutoPushPage.qml") Button { id: btn3 text: "push_autoPushPage" onClicked: { console.debug("Clicked") stackview.push(autoPushPage) } } }
This is the output:
qml: Depth: 1 qml: Depth: 2 qml: Clicked qml: Depth: 3 file:///.../Code/testStackView/main.qml:11:5: QML StackView: cannot push while already in the process of completing a push
So on startup the automatic push works. But when the button is clicked there seems to be a race condition that
StackView
is not waiting until 1 push finishes to start the next push.My question is: How can I properly remove transitions without causing race conditions?
(Or alternatively: How can I push a page immediately on the stack once another page is there (based on some conditionisDeviceConnected
)) -
Hi, and welcome!
@dominio said in How to remove StackView Transitions:
How can I properly remove transitions without causing race conditions?
See https://doc.qt.io/qt-6/qml-qtquick-controls-stackview.html#transitions -- Assign an empty
Transition {}
to the 6*Enter
and*Exit
properties -
Thank you @JKSH
I have changed my
main.qml
to// main.qml import QtQuick 2.15 import QtQuick.Window 2.15 import QtQuick.Controls 2.15 Window { width: 640 height: 480 visible: true title: qsTr("Hello World") StackView { id: stackview onDepthChanged: console.debug(`Depth: ${depth}`) initialItem: AutoPushPage {} pushEnter: Transition {} pushExit: Transition {} popEnter: Transition {} popExit: Transition {} replaceEnter: Transition {} replaceExit: Transition {} } }
but the problem is the same
-
The problem, according to the error message, is that the first StackView.push() doesn't complete before the second one begins. A transition creates some asynchronous work, allowing the push() to complete. The solution would appear to be to schedule some work. This was successful for me:
// main.qml import QtQuick 2.15 import QtQuick.Window 2.15 import QtQuick.Controls 2.15 Window { visible: true StackView { id: stackview onDepthChanged: console.debug(`Depth: ${depth}`) initialItem: AutoPushPage {} pushEnter: Transition { XAnimator { duration: 0 } } pushExit: Transition { XAnimator { duration: 0 } } } }
Using Qt.callLater() to invoke StackView.push() looks like another solution. When I tried, the application crashed. I didn't bother to investigate. A 0 interval Timer should work in the same way, for a little more code.