In my implementation, I am storing initial coordinate on mouse press event and comparing initial coordinate with coordinate on mouse release event.In this code I have not considered speed of swipe but we can easily measure speed of swipe by measuring time difference between two event.
myswipegesture.h file
#ifndef MYSWIPEGESTURE_H #define MYSWIPEGESTURE_H #include <QObject> #include <QPoint> class MySwipeGesture : public QObject { Q_OBJECT public: explicit MySwipeGesture(QObject *parent = 0); void handleEvent( QEvent *event); public: enum SwipeDirection { Left = 0, Right, Up, Down }; signals: void handleSwipe( MySwipeGesture::SwipeDirection direction ); private: QPoint _startPoint; QPoint _endPoint; }; #endif // MYSWIPEGESTURE_Hmyswipegesture.cpp file
#include "myswipegesture.h" #include <QEvent> #include <QMouseEvent> MySwipeGesture::MySwipeGesture(QObject *parent) :QObject(parent),_startPoint(0,0),_endPoint(0,0) {} void MySwipeGesture::handleEvent( QEvent *event) { if( event->type() == QEvent::MouseButtonPress ) { QMouseEvent* mouseEvent = static_cast<QMouseEvent*> (event); _startPoint = mouseEvent->pos(); } else if( event->type() == QEvent::MouseButtonRelease ) { QMouseEvent* mouseEvent = static_cast<QMouseEvent*> (event); _endPoint = mouseEvent->pos(); //process distance and direction int xDiff = _startPoint.x() - _endPoint.x(); int yDiff = _startPoint.y() - _endPoint.y(); if( qAbs(xDiff) > qAbs(yDiff) ) { // horizontal swipe detected, now find direction if( _startPoint.x() > _endPoint.x() ) { emit handleSwipe( Left); } else { emit handleSwipe( Right); } } else { // vertical swipe detected, now find direction if( _startPoint.y() > _endPoint.y() ) { emit handleSwipe( Up); } else { emit handleSwipe( Down); } } } else if( event->type() == QEvent::MouseMove ) { //ignore event } }Some test code.
#include "myswipegesture.h" TestWidget::TestWidget(QWidget *parent) : QWidget(parent) { _swipeGesture = new MySwipeGesture(this); connect(_swipeGesture,SIGNAL(handleSwipe(MySwipeGesture::SwipeDirection)),this,SLOT(swipe(MySwipeGesture::SwipeDirection))); } bool TestWidget::event(QEvent *event) { _swipeGesture->handleEvent(event); return QWidget::event(event); } void TestWidget::swipe(MySwipeGesture::SwipeDirection direction) { qDebug() << "swipe" << direction; }Hope this helps.
Wow, looks like a nice piece of code - now to go and learn c++/QT to see how to implement it!!!
ReplyDeleteTis just the test code part that i can't get compiling :P
(me @ mywebsiteaddy .com)
Glad that you liked it :)
ReplyDeleteGreate piece of code, thanks!
ReplyDeleteThanks :)
ReplyDeleteThanks a lot.. It really helped me!
ReplyDeleteYou are welcome :) I m glad that it helped you.
ReplyDeleteHey Kunal !
ReplyDeleteThanks ! This was just what I was looking for !
I am implementing my UI in QML and tried many things with GestureArea, MouseArea etc.
Can u show an example how to link this with QML, I mean, its like this :
If swipe detected, do this in QML
And, is this only for horizontal or vertical swipe, can we get the angle ?
Thanks !!!
For angle, you can get slop of line ( start point and end point) and from slop you can get angle.
ReplyDeleteSame thing can be implemented in QML using MouseArea and handiling onPressed and onReleased event. I will try to put some example here.
Hey Kunal!
ReplyDeleteI have 2 windows. One is a main window and second a new window. I want to go to new window from main window and vice versa by scrolling(using mouse on simulator and touch on device) and not by any pushbutton or anything else.
Could you help something in this case?
Thanks in advance.
I guess, you already know that how to switch window, i you can use QStackedWidget or for QML I have a blog post to swich QML screen.
ReplyDeleteNow you need is to detect swipe direction and activate appropriate window.
can you provide some code with detecting swipe direction ? i really have no idea how to implement this thing.
ReplyDeletethis post shows, how to detect the swipe as well as its direction, for example handleSwipesignal indicate swipe in right direction - >emit handleSwipe( Right);
ReplyDeletePlease check the code in post.
what is " some test code" ?
ReplyDeletetest code, which test my implementation
ReplyDeletewhere should i write this code? what name?
ReplyDeleteyour widget class, where you want to detect swipe gesture
ReplyDelete\test\main.cpp:12: error: 'class MySwipeGesture' has no member named 'show'. I got this error. Can you tell something about this? I kept your test code as testwidget.cpp
ReplyDeleteEven if i dont include your test code, the error remains the same
ReplyDeleteI think you should go through some nice widget programming tutorial first, once you understand basic widget programming with Qt, then you will easily follow this post.
DeleteHi Kunal,
ReplyDeleteWill it be possible for you to show the same example in QML,
I have been trying swiping left and right among different pages of my application using QML logic, but the swipe is coming terrible :)
I have been using the following logic to do that ,
onTouch: {
if (event.isDown()) {
downX = event.windowX;
downY = event.windowY;
} else if (event.isUp()) {
var yDiff = downY - event.windowY;
// take absolute value of yDiff
if (yDiff < 0) yDiff = -1 * yDiff;
// I check if the minimum y movement is less than 200. Don't want to move left or right if
// the user is actually want to move up or down.
if ((yDiff) < 200) {
if ((downX - event.windowX) > 320) {
console.debug("appsList.qml onTouch... move left");
_app.LoadWebLinkPage();
} else if ((event.windowX - downX) > 320) {
console.debug("appsList.qml onTouch... move right");
_app.LoadFavoritePage();
}
}
}
}
Can you suggest some better approach
Hi, I will try to post same sample code for QML as well.
DeleteThanks very much Kunal , I will wait for your sample code !!
ReplyDeleteHello, I added code here, http://kunalmaemo.blogspot.kr/2014/04/creating-custom-swipe-handler-in-qml.html
DeleteI like it!!
ReplyDeleteHelped me a lot to move around my stacked widget items on android :-)
I will credit you in my source code