Unsolved QML Binding loop detected for property, what is the cause?
-
I'm working on a project and trying to improve the error handling, this is driving me crazy. No matter what I try I'm still getting 3 QML messages on start-up that I just don't understand the cause of:
qrc://qml/Modes/ModePreview.qml:185:17: QML ModeSelection: Binding loop detected for property "selectedItemIndex"
In the original code I thought the cause of this was a reference to an object that was not ready so I added a JavaScript function to test the object exhaustively before trying to access the property. This is the part of the QML that is causing the issues:
StackLayout { id: stackLayout anchors.top: tabBar.bottom anchors.left: tabBar.left anchors.right: tabBar.right anchors.bottom: cameraSelector.top currentIndex: tabBar.currentIndex readonly property int tabIndexLocal: 0 readonly property int tabIndexMachine: 1 readonly property int tabIndexTemplates: 2 property var currentItem: children[currentIndex] property var lastSelected: ["","",""] function handleSelectedPathChanged(path) { if ( typeof path == "object" && typeof path.length == "number" && path.length > 0) { workingModeSelected = false } } function getItem(member) { if ( typeof stackLayout.currentItem == "object" && typeof stackLayout.currentItem[member] != "undefined" ) { return stackLayout.currentItem[member]; } return -1; } function pathChanged(index, selectedPath) { var rc = false; if ( index >= stackLayout.tabIndexLocal && index <= stackLayout.tabIndexTemplates ) { if ( typeof selectedPath == "object" && typeof selectedPath.length == "number" && selectedPath.length > 0 ) { if ( typeof stackLayout.lastSelected[index] === "string" && stackLayout.lastSelected[index] !== selectedPath[0] ) { stackLayout.lastSelected[index] = selectedPath[0]; rc = true; } } } return rc; } ModeSelection { id: localModesList modeType: ModePreviewManager.LocalModeType modePreviewModel: modePreviewManager.localModes onModePreviewModelChanged: selectedPath = [] onSelectedPathChanged: { stackLayout.handleSelectedPathChanged(selectedPath); if ( stackLayout.pathChanged(stackLayout.tabIndexLocal, selectedPath) === true ) { modeSelectionArea.refreshHighlight(); } } } ModeSelection { id: machineModesList modeType: ModePreviewManager.MachineModeType modePreviewModel: modePreviewManager.machineModes onModePreviewModelChanged: selectedPath = [] onSelectedPathChanged: { stackLayout.handleSelectedPathChanged(selectedPath) if ( stackLayout.pathChanged(stackLayout.tabIndexMachine, selectedPath) === true ) { modeSelectionArea.refreshHighlight(); } } onItemCountChanged: { if ( machineModesList.itemCount > 0 ) { tabBar.currentIndex = stackLayout.tabIndexMachine machineModesList.setSelected(machineModesList.itemCount - 1); ModeDetails.stopBusyAnim(); } } } ModeSelection { id: templateModeList modeType: ModePreviewManager.TemplateModeType modePreviewModel: modePreviewManager.templateModes onModePreviewModelChanged: selectedPath = [] onSelectedPathChanged: { stackLayout.handleSelectedPathChanged(selectedPath) if ( stackLayout.pathChanged(stackLayout.tabIndexTemplates, selectedPath) === true ) { modeSelectionArea.refreshHighlight(); } } } }
What is causing the loop?
-
@SPlatten Which is the line 185?
-
It doesn't really make much sense, line 185 is the line starting "ModeSelection {", this is the first "ModeSelection {" with "id: localModesList" which is also the tab I am currently viewing.
-
@SPlatten I think the problem is inside ModelSelection.qml, take a closer look at property
selectedItemIndex
from this QML element. I think it is a custom component. -
I'm quite new to QML, is there any error handling I can introduce that would help me trace this?
In the file ModeSelection.qml, near the top along with some other properties:
property int selectedItemIndex: { //Some logic to get the index, if it fails return -1 }
-
@SPlatten said in QML Binding loop detected for property, what is the cause?:
I'm working on a project and trying to improve the error handling, this is driving me crazy. No matter what I try I'm still getting 3 QML messages on start-up that I just don't understand the cause of:
qrc://qml/Modes/ModePreview.qml:185:17: QML ModeSelection: Binding loop detected for property "selectedItemIndex"
What is causing the loop?
My comment is just a sidenote. Please forgive the intrusion. It comes from empathy and I will be brief.
I've struggled with these, too. The thought that crosses my mind is that something in the codebase (in "qtdeclarative/src" or similar) must be traversing the bits that are circularly linked, so why not print out the cycle along with the "binding loop detected"? I've seen several build tools and compilers do exactly that (print the whole cycle) when they detect cyclic dependencies. One of these days I hope to have time to propose such an enhancement and draft a patch.
-
I think the issue was caused by the fact that the property is no assigned a constant but a JavaScript which for some reason was erring and I think because of the error the value assigned to the property was undefined.