Important: Please read the Qt Code of Conduct -

Qt Swipe Gesture Propagation using QGesturerecogniser

  • I've re-implemented QStackedWidget and installed a swipe gesture recogniser. I have a StackedWidget inside another StackedWidget as we can see in the image , i want that the parent widget only accepts horizontal "swipes" and the child vertical "swipes" if i make the swipe gesture in the child, the parent doesn't receive the event, is there a way to propagate the child gesture event to parent?

    swipe gesture implementation
    bool SlidingStackedWidget::event(QEvent *event)
    if (event->type() == QEvent::Gesture){

        return gestureEvent(static_cast<QGestureEvent*>(event));
    return QWidget::event(event);


    bool SlidingStackedWidget::gestureEvent(QGestureEvent *event)
    if (QGesture *swipe = event->gesture(Qt::SwipeGesture))
    swipeTriggered(static_cast<QSwipeGesture *>(swipe));
    // else if (QGesture *pan = event->gesture(Qt::PanGesture))
    // panTriggered(static_cast<QPanGesture *>(pan));
    // if (QGesture *pinch = event->gesture(Qt::PinchGesture))
    // pinchTriggered(static_cast<QPinchGesture *>(pinch));
    // if (QGesture *tap = event->gesture(Qt::TapGesture))
    // tapTriggered(static_cast<QTapGesture *>(tap));
    // if (QGesture *tapandhold = event->gesture(Qt::TapAndHoldGesture))
    // {
    // //tapandholdTriggered(static_cast<QTapAndHoldGesture *>(tapandhold));
    // }
    return true;

    recognizer implementation:
    // virtual
    SwipeGestureRecognizer::recognize(QGesture* pGesture, QObject *pWatched, QEvent *pEvent)

    QGestureRecognizer::Result result = QGestureRecognizer::Ignore;
    QSwipeGesture *pSwipe = static_cast<QSwipeGesture*>(pGesture);
    switch(pEvent->type()) {
    case QEvent::MouseButtonPress: {
        QMouseEvent* pMouseEvent = static_cast<QMouseEvent*>(pEvent);
        pSwipe->setProperty("startPoint", pMouseEvent->pos());
        result = QGestureRecognizer::MayBeGesture;
    case QEvent::MouseMove:{
        QMouseEvent* pMouseEvent = static_cast<QMouseEvent*>(pEvent);
        if(pMouseEvent->buttons() == Qt::LeftButton){
    case QEvent::MouseButtonRelease: {
        QMouseEvent* pMouseEvent = static_cast<QMouseEvent*>(pEvent);
        const QVariant& propValue = pSwipe->property("startPoint");
        QPointF startPoint = propValue.toPointF();
        QPointF endPoint = pMouseEvent->pos();
        // process distance and direction
        int dx = endPoint.x() - startPoint.x();
        int dy = endPoint.y() - startPoint.y();
        if (!IsValidMove(dx, dy)) {
            // Just a click, so no gesture.
            result = QGestureRecognizer::CancelGesture;
        } else {
            qint64 miliSec = timer.restart();
            if (miliSec > 500)
                return QGestureRecognizer::CancelGesture;
            // Compute the angle.
            qreal angle = ComputeAngle(dx, dy);
            qDebug()<<"Angle:"<<pSwipe->swipeAngle()<<" : "<<pWatched;
            result = QGestureRecognizer::FinishGesture;
    return result;

    After some debugging i noticed that that SwipeGestureRecognizer::recognize is called only in child.

  • Lifetime Qt Champion

    Hi and welcome to devnet,

    IIRC, you need to ignore the event if you don't handle it so that it gets sent to the parent widget.

    Hope it helps

  • Hi, thanks for the reply

    in the recognizer implementation line 11 i ignore the event bey setting pEvent->setAccepted(false);

    I notice that other events are passed to parent SlidingStackedWidget like mousepress and mousemove but SwipeGestureRecognizer::recognize is only called in child.

  • Lifetime Qt Champion

    Sorry, I didn't notice that one, I'm more used to ignore. By the way, why are you returning true since you don't always handle the event ?

Log in to reply