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. Distinguishing direction of swipe and changing states accordingly in QML

Distinguishing direction of swipe and changing states accordingly in QML

Scheduled Pinned Locked Moved QML and Qt Quick
12 Posts 4 Posters 11.5k Views
  • 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
    kyleplattner
    wrote on last edited by
    #1

    This should be fairly simple but I am not sure how to complete it. Lets say I have several states that I want to switch between by swipe events so that when the user swipes to the left it goes back one state and when the user swipes to the right it goes forward one state. Any help would be appreciated. Thanks,

    Kyle

    1 Reply Last reply
    0
    • A Offline
      A Offline
      andre
      wrote on last edited by
      #2

      I assume you are using the GestureArea QML element, right?
      The onSwipe signal has an angle argument. You can use that to distinguish a direction. I don't know what the scale (degrees? rads?) or what the 0 point is (top? right?), but you should be able to figure that out yourself easily. Say that the scale are degrees and the top is 0, then you can interpret anything between 315 and 360 and between 0 and 45 as a swipe to the top, between 45 and 135 to the right, between 135 and 225 to the bottom, and between 225 and 315 to the left.

      The state system in QML is quite basic (there were discussions on integrating the much more powerful Qt statemachines into QML here or on the qml mailinglist before), but in principle, you can just change the qml state that controls in what state your application is on such a swipe.

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

        I would like to do with with just a mousearea so I don't have to use a labs plugin. This will be necessary to move to my target device, openembedded linux. Any solutions with mousearea?

        1 Reply Last reply
        0
        • A Offline
          A Offline
          andre
          wrote on last edited by
          #4

          Well, in that case, you would basically have to make your own gesture recognition. For a very basic recognition, store the x and of the mouse when you receive the onPressed signal, and compare with the x and y when you get onReleased. If the x on release is (much) bigger than on pressed, and the y is about the same, you have a swipe to the right. You probably want to add the time it took into the picture, as well as detours along the way (a half circle is not the same as a swipe, even though they can start and end in the same place).

          Are you sure you can't use the one from labs somehow?

          1 Reply Last reply
          0
          • K Offline
            K Offline
            kyleplattner
            wrote on last edited by
            #5

            I believe I understand the concept, I am just not sure how to accomplish it in qml. Deploying plugins to openembedded has been a large nightmare in the past.

            1 Reply Last reply
            0
            • M Offline
              M Offline
              matrixx
              wrote on last edited by
              #6

              I have implemented the swipe gesture in my QML jewel-game. I'll paste the code (JavaScript) which handles the swipe gesture check for MouseArea component here. The code is my game specific, but I'm sure you'll get the idea :)
              @
              function handleSwipe(srcX, srcY, destX, destY) {
              var col = Math.floor(srcX / gameCanvas.blockSize);
              var row = Math.floor(srcY / gameCanvas.blockSize);
              if (col >= maxColumn || col < 0 || row >= maxRow || row < 0)
              return false;

              var deltax = destX - srcX;
              var deltay = destY - srcY;
              var success = false;
              if (Math.abs(deltax) > 50 || Math.abs(deltay) > 50) {
                  if (deltax > 30 && Math.abs(deltay) < 30) {
                      // swipe right
                      success = trySwap(col, row, col + 1, row);
                  } else if (deltax < -30 && Math.abs(deltay) < 30) {
                      // swipe left
                      success = trySwap(col, row, col - 1, row);
                  } else if (Math.abs(deltax) < 30 && deltay > 30) {
                      // swipe down
                      success = trySwap(col, row, col, row + 1);
                  } else if (Math.abs(deltax) < 30 && deltay < 30) {
                      // swipe up
                      success = trySwap(col, row, col, row - 1);
                  }
                  if (success) {
                      shuffleDown();
                      fillBoard();
                      return true;
                  }
              }
              return false;
              

              }
              @

              Nokia Certified Qt Specialist

              1 Reply Last reply
              0
              • K Offline
                K Offline
                kyleplattner
                wrote on last edited by
                #7

                Could you help me understand how your JavaScript integrated into your QML mousearea and where I would need to modify our JavaScript?

                How could I have the JavaScript tell my mousearea when a gesture is signaled. In other words, I would love to have my mouse area designed like:

                Mousearea{
                ...
                onGestureLeft:
                }

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  andre
                  wrote on last edited by
                  #8

                  You can achieve that by creating your own QML component with the appropriate signals.
                  Adapt the code example above to emit such a signal on the different swipes that it recognizes (see the inline comments on when that is).

                  On the start of your mouse interaction, you store the begin coordinates xB and yB. If you want to recognize the swipe only when the interaction is over, you then use the onReleased signal of the mouseArea. If you want to do continuous recognition, use the onPositionChanged signal. When you get the required signal, run the code above using the xB and yB and the new coordinates that are passed with the signal.

                  1 Reply Last reply
                  0
                  • K Offline
                    K Offline
                    kyleplattner
                    wrote on last edited by
                    #9

                    Forgive my inexperience but could you give me an example of what that would look like?

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      andre
                      wrote on last edited by
                      #10

                      From the top of my head, I did not try it out:

                      @
                      //in a file called MyGestureArea.qml (casing important!)

                      MouseArea {
                      signal swipeRight;
                      signal swipeLeft;
                      signal swipeUp;
                      signal swipeDown;

                      property int startX;
                      property int startY;
                      
                      onPressed: {
                          startX = mouse.x;
                          startY = mouse.y;
                      }
                      
                      onReleased: {
                      var deltax = mouse.x - startX;
                      var deltay = mouse.y - startY;
                      
                      if (Math.abs(deltax) > 50 || Math.abs(deltay) > 50) {
                          if (deltax > 30 && Math.abs(deltay) < 30) {
                              // swipe right
                              swipeRight();
                          } else if (deltax < -30 && Math.abs(deltay) < 30) {
                              // swipe left
                              swipeLeft();
                          } else if (Math.abs(deltax) < 30 && deltay > 30) {
                              // swipe down
                              swipeDown();
                          } else if (Math.abs(deltax) < 30 && deltay < 30) {
                              // swipe up
                              swipeUp();
                          }
                      }
                      

                      }
                      @

                      Then, you should be able to use a MyGestureArea instead of a MouseArea, and be able to use onSwipeRight and onSwipeDown event handlers. Again: I did not test the above. See it as pseudocode please :-)

                      1 Reply Last reply
                      0
                      • K Offline
                        K Offline
                        kyleplattner
                        wrote on last edited by
                        #11

                        That worked great but it does not play well with my other mouseareas on the page. I laid the gesture sensing mousearea over the whole page which contains mousareas for buttons.

                        1 Reply Last reply
                        0
                        • M Offline
                          M Offline
                          music24by7
                          wrote on last edited by
                          #12

                          Thank you guys, I was looking out for an example as this: I implemented it as below in my flip area

                          @MouseArea{
                          id:myFlipMouseArea
                          anchors.fill: myFlip
                          property int startX;
                          property int startY;
                          onPressed: {
                          startX = mouse.x;
                          startY = mouse.y;
                          }

                              onReleased: {
                                  var deltax = mouse.x - startX;
                                  var deltay = mouse.y - startY;
                          
                                  if (Math.abs(deltax) > 40 || Math.abs(deltay) > 40) {
                                      if (deltax > 30 && Math.abs(deltay) < 30) {
                                          // swipe right
                                      } else if (deltax < -30 && Math.abs(deltay) < 30) {
                                          // swipe left
                                          myFlip.flipped = !myFlip.flipped
                                          console.log("swipeLeft");
                                      } else if (Math.abs(deltax) < 30 && deltay > 30) {
                                          // swipe down
                                      } else if (Math.abs(deltax) < 30 && deltay < 30) {
                                          // swipe up
                                          console.log("swipeUp");
                                          currentWord += 1;
                                          flipWord.modifyContents();
                                      }
                                  }
                              }
                          }@
                          
                          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