Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. How to break property bindings to c++ QObjects
Forum Updated to NodeBB v4.3 + New Features

How to break property bindings to c++ QObjects

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
7 Posts 4 Posters 1.1k Views 3 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.
  • K Offline
    K Offline
    kgregory
    wrote on last edited by kgregory
    #1

    So I found lots of documentation about how to create property bindings in QT, but not so much how to un-bind those properties.

    In my application, I have a list of QObjects that the user can select and then interact with. Initially, it loads some data for those objects and then initializes some QtQuick controls in the app GUI with that data, then binds the control values to the objects. In QtQuick, I use the javascript such as the following to set that up:

        MyComboBox{
            id: thisCombobox
    
            ...
    
            Component.onCompleted: {
                thisCombobox.currentIndex = (myMainObject.myTargetObject.someProperty)
                myMainObject.myTargetObject.someProperty = Qt.binding(function() { return (thisComboBox.currentIndex) })
            }
            Connections {
                target: myMainObject
                onTargetChanged: {
                    thisComboBox.currentIndex = (myMainObject.myTarget.someProperty)  //Note: myTarget now points to a different object from before
                    myMainObject.myTarget.someProperty = Qt.binding(function() { return (thisComboBox.currentIndex) })
                }
            }
        }
    

    My problem is that when the user selects a new target object, the property binding to the other object is maintained and now the combobox is changing properties for two objects at once (or more after each new selection).

    Can anyone advise me on what are my options for breaking these bindings that have been setup when they are no longer wanted?

    I think one possible solution could be for my object to emit a separate signal just before a new target is selected so that these bindings can be broken, however, if there is a way within the C++ code to break all bindings prior to a target change, then that might be a much simpler solution for me.

    Edit: to clarify the above code snippet here are some definitions:

    • thisComboBox is a custom version of QComboBox that I have made in QML. Though it could be any QControl class for the purpose of this thread.
    • myMainObject is the main C++ object within my application. Noteably, it contains a list of similar child objects that I am selectively binding to thisComboBox
    • myTarget is a pointer to a QObject. This pointer identifies which, out of the aforementioned list of QObjects, should be bound to thisComboBox
    • someProperty is the property of the chosen child QObject that should be bound to thisComboBox
    • onTargetChanged is a signal that is emitted by myMainObject when myTarget changes to point to a new QObject
    1 Reply Last reply
    0
    • sierdzioS Offline
      sierdzioS Offline
      sierdzio
      Moderators
      wrote on last edited by
      #2
      Item {
        id: thatItem
        // This establishes a binding
        visible: someObject.someProperty
      }
      
      // This breaks the binding
      thatItem.visible = false
      

      Also, you can use Binding QML component to set up bindings more explicitly, and to have more control over them.

      (Z(:^

      1 Reply Last reply
      1
      • K Offline
        K Offline
        kgregory
        wrote on last edited by
        #3

        The problem is I'm binding to my C++ QObject and in QML I no longer have a handle to the old target object when I get the signal to bind to a new target object.

        From my current understanding of bindings, I can see two possible solutions:

        1. I can emit an additional signal before the target is changed to tell QML to break the binding while it still has a handle to the old target.
        2. Add a property to my main QObject which has a pointer to the previous target, this way QML has a way of knowing which object to break the binding for.

        I was hoping there would be a way to break the binding in C++ or to just break the bindings to all of the objects. Perhaps I can do this with a for loop, I'll have to sharpen my java skills, though.

        1 Reply Last reply
        0
        • fcarneyF Offline
          fcarneyF Offline
          fcarney
          wrote on last edited by
          #4

          @kgregory said in How to break property bindings to c++ QObjects:

          The problem is I'm binding to my C++ QObject and in QML I no longer have a handle to the old target object when I get the signal to bind to a new target object.

          What mechanism causes "thisComboBox" to no longer be the object you want to be bound to? Can this object be assigned to a higher level property and have the value bound to that property?

          C++ is a perfectly valid school of magic.

          K 1 Reply Last reply
          0
          • fcarneyF fcarney

            @kgregory said in How to break property bindings to c++ QObjects:

            The problem is I'm binding to my C++ QObject and in QML I no longer have a handle to the old target object when I get the signal to bind to a new target object.

            What mechanism causes "thisComboBox" to no longer be the object you want to be bound to? Can this object be assigned to a higher level property and have the value bound to that property?

            K Offline
            K Offline
            kgregory
            wrote on last edited by
            #5

            @fcarney this last line of the code I posted above binds property someProperty of myTarget (myTarget is a pointer to a QObject) to currentIndex of thisComboBox:

            myMainObject.myTarget.someProperty = Qt.binding(function() { return (thisComboBox.currentIndex) })

            So whenever you interract with thisComboBox, someProperty gets a new value.

            Again, myTarget is a pointer to a QObject, one of many similar QObjects that I hold in a list within myMainObject. myTarget can change based on user input to point to any of these QObjects from my list. So, when myTarget points at a new object, both the new object and the old object are bound to thisComboBox whereas I would like only the current object that myTarget points to to be bound.

            1 Reply Last reply
            0
            • jeremy_kJ Offline
              jeremy_kJ Offline
              jeremy_k
              wrote on last edited by
              #6

              I suggest restructuring the bindings to avoid changing them after creation of the control.

              MyComboBox {
                id: thisComboBox
              
                onCurrentIndexChanged:  myMainObject.myTarget.someProperty = thisComboBox.currentIndex
              
                Connections {
                  target: myMainObject
                  onTargetChanged: thisComboBox.currentIndex = myMainObject.myTarget.someProperty
                }
              }
              

              Asking a question about code? http://eel.is/iso-c++/testcase/

              1 Reply Last reply
              0
              • fcarneyF Offline
                fcarneyF Offline
                fcarney
                wrote on last edited by
                #7

                Look into conditional binding:
                https://doc.qt.io/qt-5/qml-qtqml-binding.html#conditional-bindings
                At some point you bind to the value based upon a condition. That would be in the when clause:

                Binding { 
                  target: myMainObject.myTarget
                  property: "someProperty"
                  value: thisComboBox.currentIndex
                  when: <some condition>
                }
                

                You might want to look at restoreMode in case you have a value or binding you need to restore.

                C++ is a perfectly valid school of magic.

                1 Reply Last reply
                1

                • Login

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