Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Call for Presentations - Qt World Summit

    Bypassing binding loops

    QML and Qt Quick
    2
    3
    996
    Loading More Posts
    • 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.
    • B
      Babalas last edited by

      I've got a timeline UI where basically each element is positioned based on some model data. For instance the x coordinate is based on the seconds and the width is based on the duration of the element.
      @
      width: modelData.duration * pixelSecondWidth
      x: modelData.seconds * pixelSecondWidth + 1
      @

      Then I try to use a MouseArea to drag the element around or drag handles at the beginning and end of the element. The problem I have is that if I use @onXChanged@ to store the seconds back into the modelData I get a binding loop. If I don't, then the element moves fine but the value doesn't update (obviously).

      So I can think of three potential ways to do this:

      Is there a way of setting the width without creating a binding?

      Can I somehow create an intermediate step inbetween that handles the conversion between seconds and duration to coordinates and back without messing with the C++ model?

      Is there some way to get the mouse delta rather than mouse position during a drag?

      1 Reply Last reply Reply Quote 0
      • J
        JapieKrekel last edited by

        Setting a property using an assignment will do without binding

        @Component.onCompleted: width = modelData.duration * pixelSecondWidth@

        1 Reply Last reply Reply Quote 0
        • B
          Babalas last edited by

          What I've ended up with is
          @
          Component.onCompleted: {
          width = modelData.duration * pixelSecondWidth
          x = modelData.seconds * pixelSecondWidth + 1
          }

              Connections {
                  target: modelData
                  onDurationChanged: {
                      if (!mouse.drag.active)
                      {
                          property.width = modelData.duration * pixelSecondWidth
                      }
                  }
          
                  onSecondsChanged: {
                      if (!mouse.drag.active)
                      {
                          property.x = modelData.seconds * pixelSecondWidth + 1
                      }
                  }
              }
          
              onWidthChanged: {
                  if(mouse.drag.active)
                      modelData.duration = width / pixelSecondWidth
              }
          
              onXChanged: {
                  if (mouse.drag.active)
                      modelData.seconds = (x - 1) / pixelSecondWidth
              }
          

          @

          I figure there must be a way to do this with Bindings somehow. May play around later. Thinking something like:
          @
          Binding on width { when: mouse.drag.active; value: ...}
          @

          1 Reply Last reply Reply Quote 0
          • First post
            Last post