Qt Forum

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

    Unsolved How to implement “Snap While Dragging” behavior in QML?

    QML and Qt Quick
    1
    1
    218
    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.
    • W
      wcomp last edited by

      I'm looking to achieve a "snap while dragging" behavior in QML. Specifically, within my example below, when the element being dragged (red column) reaches a location on the x axis that is inside the "snap area" (orange column), it snaps to the middle of the snap area and sticks there until the mouse pointer is again outside the snap area, at which point the dragged element should snap to the current position of the mouse pointer and the drag continues on it's way. Here is what I have so far:

      import QtQuick 2.12
      import QtQuick.Window 2.12
      
      Window {
          id: main_window
          width: 640
          height: 480
          visible: true
          visibility: Window.Maximized
      
          property double x_location: square.x
          property double y_location: square.y
      
          property double start_x_of_snap_area: snap_area.x
          property double end_x_of_snap_area: snap_area.x + snap_area.width
      
          property bool is_handlebar_inside_snap_area: false
      
          onX_locationChanged: function () {
              if (x_location >= start_x_of_snap_area
                      && square.x + square.width <= end_x_of_snap_area) {
                  is_handlebar_inside_snap_area = true
              } else {
                  is_handlebar_inside_snap_area = false
              }
          }
      
          onIs_handlebar_inside_snap_areaChanged: function () {
              if (is_handlebar_inside_snap_area === true) {
                  console.log(dragArea.drag.target)
                  dragArea.drag.target = null
                  square.anchors.horizontalCenter = snap_area.horizontalCenter
              }
          }
      
          Text {
              y: 0
              text: "start_x_of_snap_area: " + start_x_of_snap_area
              font.pixelSize: 30
          }
      
          Text {
              y: 50
              text: "end_x_of_snap_area: " + end_x_of_snap_area
              font.pixelSize: 30
          }
      
          Text {
              y: 100
              text: "is_handlebar_inside_snap_area: " + is_handlebar_inside_snap_area
              font.pixelSize: 30
          }
      
          Rectangle {
              id: snap_area
              height: parent.height
              width: 200
              anchors.centerIn: parent
              color: 'orange'
      
              Text {
                  text: "snap area"
                  font.pixelSize: 30
                  anchors.centerIn: parent
              }
          }
      
          Rectangle {
              id: square
              width: 50
              height: main_window.height
              color: 'red'
              opacity: .7
              Drag.active: dragArea.drag.active
      
              Text {
                  text: 'x: ' + x_location + ' y: ' + y_location
                  font.pixelSize: 10
                  color: 'white'
                  anchors.centerIn: parent
                  font.family: 'Arial'
              }
      
              MouseArea {
                  id: dragArea
                  drag {
                      target: parent
                      axis: "XAxis"
                      minimumX: 0
                      maximumX: main_window.width - square.width
                  }
                  anchors.fill: parent
                  cursorShape: Qt.SizeAllCursor
              }
          }
      }
      

      Some problems with the above code is once the snap happens, its stuck. Also, if you move the mouse pointer really fast over the snap area the function doesn't fire quick enough to give satisfactory results (it doesn't work at all).

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