Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QML Binding loop detected for property, what is the cause?
Forum Updated to NodeBB v4.3 + New Features

QML Binding loop detected for property, what is the cause?

Scheduled Pinned Locked Moved Unsolved General and Desktop
7 Posts 4 Posters 3.3k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • SPlattenS Offline
    SPlattenS Offline
    SPlatten
    wrote on last edited by
    #1

    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?

    Kind Regards,
    Sy

    KH-219DesignK 1 Reply Last reply
    -1
    • jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @SPlatten Which is the line 185?

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • SPlattenS Offline
        SPlattenS Offline
        SPlatten
        wrote on last edited by SPlatten
        #3

        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.

        Kind Regards,
        Sy

        KroMignonK 1 Reply Last reply
        0
        • SPlattenS SPlatten

          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.

          KroMignonK Offline
          KroMignonK Offline
          KroMignon
          wrote on last edited by KroMignon
          #4

          @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.

          It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

          1 Reply Last reply
          0
          • SPlattenS Offline
            SPlattenS Offline
            SPlatten
            wrote on last edited by
            #5

            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
                }
            

            Kind Regards,
            Sy

            1 Reply Last reply
            0
            • SPlattenS SPlatten

              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?

              KH-219DesignK Offline
              KH-219DesignK Offline
              KH-219Design
              wrote on last edited by
              #6

              @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.

              www.219design.com
              Software | Electrical | Mechanical | Product Design

              1 Reply Last reply
              0
              • SPlattenS Offline
                SPlattenS Offline
                SPlatten
                wrote on last edited by
                #7

                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.

                Kind Regards,
                Sy

                1 Reply Last reply
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved