SwipeView with dynamic "interactive" breaks "currentIndex" binding
-
Hi,
I'm trying to create a SwipeView where the first page has the
interactive
property false, while the others have it enabled. The effect that I'm trying to achieve is to have the main page with a link to the others, but the others can only go back to the main page (like the iOS settings menu).The issue is that after the first change page, the
currentIndex
property loses binding causing the SwipeView to break.Here's the application output:
qrc:/main.qml:10:5: QML SwipeView: Binding loop detected for property "currentIndex" file:///home/rcc/Qt/5.12.6/gcc_64/qml/QtQuick/Controls.2/SwipeView.qml:49:18: QML ListView: Binding loop detected for property "currentIndex"
and here's the default swipe view application (QtCreator -> New Project -> Qt Quick Application - Swipe)
main.qml
:import QtQuick 2.12 import QtQuick.Controls 2.5 ApplicationWindow { visible: true width: 640 height: 480 title: qsTr("Tabs") SwipeView { id: swipeView anchors.fill: parent currentIndex: tabBar.currentIndex interactive: false onCurrentIndexChanged: { if (currentIndex === 0) { interactive = false } else { interactive = true } } Page1Form {} Page2Form {} } footer: TabBar { id: tabBar currentIndex: swipeView.currentIndex TabButton { text: qsTr("Page 1") } TabButton { text: qsTr("Page 2") } } }
To reproduce the bug:
- Click on Page 2.
- Swipe left.
- Click again on Page 2.
Any suggestions to solve this issue?
-
You have binding loop, as output says. You need to remove
currentIndex: tabBar.currentIndex
binding from yourSwipeView
and control its index by clicking on tab button, like this:SwipeView { id: swipeView anchors.fill: parent interactive: currentIndex Rectangle {color: "red"; opacity: 0.5} Rectangle {color: "green"; opacity: 0.5} Rectangle {color: "blue"; opacity: 0.5} } footer: TabBar { id: tabBar currentIndex: swipeView.currentIndex TabButton { text: qsTr("Page 1") onClicked: swipeView.setCurrentIndex(TabBar.index) } TabButton { text: qsTr("Page 2") onClicked: swipeView.setCurrentIndex(TabBar.index) } }
-
@IntruderExcluder said in SwipeView with dynamic "interactive" breaks "currentIndex" binding:
You have binding loop, as output says. You need to remove
currentIndex: tabBar.currentIndex
binding from yourSwipeView
and control its index by clicking on tab button, like this:SwipeView { id: swipeView anchors.fill: parent interactive: currentIndex Rectangle {color: "red"; opacity: 0.5} Rectangle {color: "green"; opacity: 0.5} Rectangle {color: "blue"; opacity: 0.5} } footer: TabBar { id: tabBar currentIndex: swipeView.currentIndex TabButton { text: qsTr("Page 1") onClicked: swipeView.setCurrentIndex(TabBar.index) } TabButton { text: qsTr("Page 2") onClicked: swipeView.setCurrentIndex(TabBar.index) } }
I've done what you say, but the problem is still here:
import QtQuick 2.12 import QtQuick.Controls 2.5 ApplicationWindow { visible: true width: 640 height: 480 title: qsTr("Tabs") SwipeView { id: swipeView anchors.fill: parent interactive: currentIndex Rectangle { color: "red" opacity: 0.5 } Rectangle { color: "green" opacity: 0.5 } Rectangle { color: "blue" opacity: 0.5 } } footer: TabBar { id: tabBar currentIndex: swipeView.currentIndex TabButton { text: qsTr("Page 1") onClicked: swipeView.setCurrentIndex(TabBar.index) } TabButton { text: qsTr("Page 2") onClicked: swipeView.setCurrentIndex(TabBar.index) } } }
Error:
file:///home/rcc/Qt/5.12.6/gcc_64/qml/QtQuick/Controls.2/SwipeView.qml:49:18: QML ListView: Binding loop detected for property "currentIndex"
By the way, I'm using Qt 5.12.6 Linux desktop.
-
I'm linking the StackOverflow question and the Qt Bug
This is the workaround suggested:
onCurrentIndexChanged: { if (currentIndex === 0) { Qt.callLater(function() { interactive = false }) } else { Qt.callLater(function() { interactive = true }) } }