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 avoid binding loop when binding to Python/C++ backend?
Forum Updated to NodeBB v4.3 + New Features

How to avoid binding loop when binding to Python/C++ backend?

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
5 Posts 4 Posters 407 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.
  • C Offline
    C Offline
    Curtwagner1984
    wrote on last edited by
    #1

    Greetings,

    I have the the following component:

    main file:

    InputPaneRow{
                    id:sourceFolderInputRow
                    Layout.preferredWidth: parent.width
                    Layout.preferredHeight: parent.height * 0.5
                    lableText: "Source Folder Path:"
                    inputPlaceHolderText: "Please Select Folder to scan."
                    inputText: gui_data.source_folder_path // <=***Binding ***
                    browseButtonText: "Browse"
                    openButtonText: "Open"
    }
    

    InputPaneRow.qml

    
    Pane{
        id:inputPaneRowRoot
        property alias lableText: inputPaneRowLabel.text
        property alias inputPlaceHolderText: inputPaneRowTextField.placeholderText
        property alias inputText: inputPaneRowTextField.text <= ***binding alias***
        property alias browseButtonText: inputPaneRowBrowseButton.text
        property alias openButtonText: inputPaneRowOpenButton.text
    
    //    background: Rectangle{
    //        color: Material.color(Material.Cyan)
    //    }
    
        signal browseButtonClicked()
        signal openButtonClicked()
    
        RowLayout {
            id:inputPaneRowRowLayout
            width: parent.width
            height: parent.height
            anchors.fill: parent
    
            Label {
                id: inputPaneRowLabel
    //            font.pixelSize: parent.height * 0.45
                Layout.preferredWidth: parent.width * 0.2
    //            Layout.minimumWidth: 180
            }
    
            TextField {
                id: inputPaneRowTextField
                Layout.preferredWidth: parent.width * 0.5
                Layout.minimumWidth: 250
            }
    
            Button{
                id: inputPaneRowBrowseButton
                Layout.minimumWidth: 50
                onClicked: {
                    inputPaneRowRoot.browseButtonClicked()
                }
            }
    
            Button{
                id: inputPaneRowOpenButton
                Layout.minimumWidth: 50
                onClicked: {
                    inputPaneRowRoot.openButtonClicked()
                }
            }
            Item{
                id:spacer
                Layout.fillWidth: true
            }
        }
    }
    

    There is a binding inputText: gui_data.source_folder_path where gui_data is a context property of a Python class and source_folder_path is a property (fully implmented with getter,setter and a notify signal).

    This binding works when the value is set from elsewhere. But I also want any text changes in inputPaneRowTextField (Which the above inputText is an alias of will also reflect those changes back to the python class.) Meaning when the user changes/types in the textfield, the property in python should be updated.

    I tried to do something like this:

    InputPaneRow{
        id:sourceFolderInputRow
        inputText: gui_data.source_folder_path
        onInputTextChanged: {
            gui_data.source_folder_path = sourceFolderInputRow.inputText
        }
    }
    

    This works (even though it obviously creates a binding loop.) I guess there is a safety measure to break those kind of loops.
    Question is, how do I reflect changes back to gui_data without using this. As far as I understand the initial binding should have been enough. Maybe it has something to do with aliasing?

    1 Reply Last reply
    0
    • C Offline
      C Offline
      Curtwagner1984
      wrote on last edited by
      #2

      No one knows?

      1 Reply Last reply
      0
      • N Offline
        N Offline
        NYBL
        wrote on last edited by NYBL
        #3

        @Curtwagner1984 said in How to avoid binding loop when binding to Python/C++ backend?:

        InputPaneRow

        Would be nice if you would describe what you are trying to do it is unclear what InputPaneRow is.
        Anyway from what I see you want two bindings for same property is that right?
        in that case you can create new property that is, say, the sum of both of them and bind to that property.
        other solution would be that the getter of the python class would return the other property as well.

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

          Can you avoid the binding in the first place and just set on creation of the component?

          InputPaneRow{
              id:sourceFolderInputRow
              //inputText: gui_data.source_folder_path
              onInputTextChanged: {
                  // if a binding is involved you should be checking if it actually needs updating, only needed if using binding
                  if(gui_data.source_folder_path !== sourceFolderInputRow.inputText)
                      gui_data.source_folder_path = sourceFolderInputRow.inputText
              }
              Component.onCompleted: inputText = gui_data.source_folder_path
          }
          

          C++ is a perfectly valid school of magic.

          1 Reply Last reply
          0
          • GrecKoG Offline
            GrecKoG Offline
            GrecKo
            Qt Champions 2018
            wrote on last edited by
            #5

            Don't use on<Property>Changed to set value back to the backend.

            You need to use the special user change signal emitted by the Control.
            If your control is a TextField the signal you want is textEdited, not textChanged.

            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