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. Restore property binding when changed
Qt 6.11 is out! See what's new in the release blog

Restore property binding when changed

Scheduled Pinned Locked Moved Solved QML and Qt Quick
6 Posts 5 Posters 2.5k 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.
  • K Offline
    K Offline
    kkettinger
    wrote on last edited by kkettinger
    #1

    Hello,

    for a settings page, i have a TextField which is connected to a c++ property:

    Q_PROPERTY(QString serialNumber READ getSerialNumber WRITE setSerialNumber NOTIFY serialNumberChanged)
    

    QML:

    TextField {
        id: textFieldSerialNumber
        value: backend.serialNumber
    }
    

    When the page is loaded, the value is displayed and changed-signals are received.

    Now the user should have an option to discard any changes made to the TextField. There is now an extra button:

    Button {
        id: buttonDiscard
        onClicked: textFieldSerialNumber= backend.serialNumber
    }
    

    This restores textFieldSerialNumber to the original value of the backend, but now it seems i've lost the binding to the c++ property and i can't receive any changes from the backend anymore.

    I see this when using another button for resetting to default values:

    Button {
        id: buttonReset
        onClicked: backend.resetSerialNumber()
    }
    

    This changes the c++ property to the default value and emits a changed() signal to qml. But because the user clicked "discard", the property is not updated anymore.

    Is there any solution only with properties?

    I appreciate any help.

    KroMignonK 1 Reply Last reply
    0
    • K kkettinger

      Hello,

      for a settings page, i have a TextField which is connected to a c++ property:

      Q_PROPERTY(QString serialNumber READ getSerialNumber WRITE setSerialNumber NOTIFY serialNumberChanged)
      

      QML:

      TextField {
          id: textFieldSerialNumber
          value: backend.serialNumber
      }
      

      When the page is loaded, the value is displayed and changed-signals are received.

      Now the user should have an option to discard any changes made to the TextField. There is now an extra button:

      Button {
          id: buttonDiscard
          onClicked: textFieldSerialNumber= backend.serialNumber
      }
      

      This restores textFieldSerialNumber to the original value of the backend, but now it seems i've lost the binding to the c++ property and i can't receive any changes from the backend anymore.

      I see this when using another button for resetting to default values:

      Button {
          id: buttonReset
          onClicked: backend.resetSerialNumber()
      }
      

      This changes the c++ property to the default value and emits a changed() signal to qml. But because the user clicked "discard", the property is not updated anymore.

      Is there any solution only with properties?

      I appreciate any help.

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

      @kkettinger said in Restore property binding when changed:

      Is there any solution only with properties?

      My way to doing this would be:

      property var aux: backend.serialNumber
      TextField {
          id: textFieldSerialNumber
          value: backend.serialNumber
      }
      
      Button {
          id: buttonDiscard
          onClicked: textFieldSerialNumber.value = backend.serialNumber // Set current value (no more updates)
      }
      
      Button {
          id: buttonReset
          onClicked:  {
              textFieldSerialNumber.value = backend.serialNumber // set current value
              textFieldSerialNumber.value = Qt.binding(function() { return backend.serialNumber} ) //"restore" connection (updated on changes)
          }
      }
      

      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
      • sierdzioS Offline
        sierdzioS Offline
        sierdzio
        Moderators
        wrote on last edited by
        #2

        This is one of the classic problems of QML :-) Check Andre's slides: https://www.kdab.com/kdab-qt-world-summit-2019/#component The video went down for some reason :-(

        In general, there is no ready-made solution for this in Qt, but there are several ways to address this problem and it can be fixed quite easily.

        (Z(:^

        1 Reply Last reply
        2
        • johngodJ Offline
          johngodJ Offline
          johngod
          wrote on last edited by
          #3

          Please check if something like this works:

          property var aux: backend.serialNumber
          TextField {
              id: textFieldSerialNumber
              value: aux
          }
          
          Button {
              id: buttonDiscard
              onClicked: aux = "some original value"
          }
          
          Button {
              id: buttonReset
              onClicked: aux = backend.serialNumber //"restore" connection 
          }
          
          1 Reply Last reply
          1
          • K kkettinger

            Hello,

            for a settings page, i have a TextField which is connected to a c++ property:

            Q_PROPERTY(QString serialNumber READ getSerialNumber WRITE setSerialNumber NOTIFY serialNumberChanged)
            

            QML:

            TextField {
                id: textFieldSerialNumber
                value: backend.serialNumber
            }
            

            When the page is loaded, the value is displayed and changed-signals are received.

            Now the user should have an option to discard any changes made to the TextField. There is now an extra button:

            Button {
                id: buttonDiscard
                onClicked: textFieldSerialNumber= backend.serialNumber
            }
            

            This restores textFieldSerialNumber to the original value of the backend, but now it seems i've lost the binding to the c++ property and i can't receive any changes from the backend anymore.

            I see this when using another button for resetting to default values:

            Button {
                id: buttonReset
                onClicked: backend.resetSerialNumber()
            }
            

            This changes the c++ property to the default value and emits a changed() signal to qml. But because the user clicked "discard", the property is not updated anymore.

            Is there any solution only with properties?

            I appreciate any help.

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

            @kkettinger said in Restore property binding when changed:

            Is there any solution only with properties?

            My way to doing this would be:

            property var aux: backend.serialNumber
            TextField {
                id: textFieldSerialNumber
                value: backend.serialNumber
            }
            
            Button {
                id: buttonDiscard
                onClicked: textFieldSerialNumber.value = backend.serialNumber // Set current value (no more updates)
            }
            
            Button {
                id: buttonReset
                onClicked:  {
                    textFieldSerialNumber.value = backend.serialNumber // set current value
                    textFieldSerialNumber.value = Qt.binding(function() { return backend.serialNumber} ) //"restore" connection (updated on changes)
                }
            }
            

            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
            • K Offline
              K Offline
              Kai Nickel
              wrote on last edited by
              #5

              You may want to have a look at the Qt.binding() function to re-activate a broken binding. See https://doc.qt.io/qt-5/qtqml-syntax-propertybinding.html#creating-property-bindings-from-javascript for details.

              1 Reply Last reply
              1
              • K Offline
                K Offline
                kkettinger
                wrote on last edited by
                #6

                Using Qt.binding() does get the job done, thank you :)

                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