Search code examples
qtqmlswipegesture

How to create a swipe effect in Qt 4.8?


I need to create a screen where the user will swipe right or left and top or down and on each of these I will present another screen. It would be like a cross where the center and each end is another screen of the system.

I tried using GestureArea, but its only event that worked was onTapAndHold, other events like onSwipe don't run. I later found out that Qt 4.8 has a bug in GestureArea and other events don't work. The problem is that the onTapAndHold event runs on click as well and I just want it to run with the swipe event.

Cross


Solution

  • Done!

    How I did it:

    import QtQuick 1.1
    import Qt.labs.gestures 1.0
    
    import "module"
    
    Rectangle {
        id: recMainWindow
        width: 800
        height: 480
        color: "#00000000"
    
        property string strActualScreen: "screenCenter"
    
        function funSwipeScreens(swipeArea)
        {
            if ((!panBottomCenter.running) && (!panCenterBottom.running) &&
                (!panCenterLeft.running) &&  (!panCenterRight.running) &&
                (!panCenterTop.running) &&  (!panLeftCenter.running) &&
                (!panRightCenter.running) &&  (!panTopCenter.running))
            {
                if (swipeArea == "top")
                {
                    if (strActualScreen == "screenBottom")
                    {
                        strActualScreen = "screenCenter";
    
                        marLeft.enabled = true;
                        marRight.enabled = true;
                        marBottom.enabled = true;
    
                        panBottomCenter.start();
                    }
                    else if (strActualScreen == "screenCenter")
                    {
                        strActualScreen = "screenTop";
    
                        marTop.enabled = false;
                        marLeft.enabled = false;
                        marRight.enabled = false;
    
                        panCenterTop.start();
                    }
                }
                else if (swipeArea == "bottom")
                {
                    if (strActualScreen == "screenTop")
                    {
                        strActualScreen = "screenCenter";
    
                        marTop.enabled = true;
                        marLeft.enabled = true;
                        marRight.enabled = true;
    
                        panTopCenter.start();
                    }
                    else if (strActualScreen == "screenCenter")
                    {
                        strActualScreen = "screenBottom";
    
                        marLeft.enabled = false;
                        marRight.enabled = false;
                        marBottom.enabled = false;
    
                        panCenterBottom.start();
                    }
                }
                else if (swipeArea == "left")
                {
                    if (strActualScreen == "screenRight")
                    {
                        strActualScreen = "screenCenter";
    
                        marBottom.enabled = true;
                        marRight.enabled = true;
                        marTop.enabled = true;
    
                        panRightCenter.start();
                    }
                    else if (strActualScreen == "screenCenter")
                    {
                        strActualScreen = "screenLeft";
    
                        marLeft.enabled = false;
                        marBottom.enabled = false;
                        marTop.enabled = false;
    
                        panCenterLeft.start();
                    }
                }
                else if (swipeArea == "right")
                {
                    if (strActualScreen == "screenLeft")
                    {
                        strActualScreen = "screenCenter";
    
                        marLeft.enabled = true;
                        marBottom.enabled = true;
                        marTop.enabled = true;
    
                        panLeftCenter.start();
                    }
                    else if (strActualScreen == "screenCenter")
                    {
                        strActualScreen = "screenRight";
    
                        marBottom.enabled = false;
                        marRight.enabled = false;
                        marTop.enabled = false;
    
                        panCenterRight.start();
                    }
                }
            }
        }
    
        Loader {
            id: loaCenter
            x: 0
            y: 0
            source: "qrc:/qml/centerScreen"
        }
    
        Loader {
            id: loaTop
            x: 0
            y: -480
            source: "qrc:/qml/topScreen"
        }
    
        Loader {
            id: loaBottom
            x: 0
            y: 480
            source: "qrc:/qml/bottomScreen"
        }
    
        Loader {
            id: loaLeft
            x: -800
            y: 0
            source: "qrc:/qml/leftScreen"
        }
    
        Loader {
            id: loaRight
            x: 800
            y: 0
            source: "qrc:/qml/rightScreen"
        }
    
        GestureArea {
            id: marLeft
            x: 0
            y: 100
            width: 100
            height: 280
            focus: true
            onTapAndHold: {
                funSwipeScreens("left");
            }
        }
    
        GestureArea {
            id: marRight
            x: 700
            y: 100
            width: 100
            height: 280
            focus: true
            onTapAndHold: {
                funSwipeScreens("right");
            }
        }
    
        GestureArea {
            id: marTop
            x: 100
            y: 0
            width: 600
            height: 100
            focus: true
            onTapAndHold: {
                funSwipeScreens("top");
            }
        }
    
        GestureArea {
            id: marBottom
            x: 100
            y: 380
            width: 600
            height: 100
            focus: true
            onTapAndHold: {
                funSwipeScreens("bottom");
            }
        }
    
        // TOP ANIMATIONS
        ParallelAnimation {
            id: panCenterTop
    
            NumberAnimation { target: loaCenter; property: "y"; from: 0; to: 480; duration: 250; easing.type: Easing.InOutQuad }
            NumberAnimation { target: loaTop; property: "y"; from: -480; to: 0; duration: 250; easing.type: Easing.InOutQuad }
        }
    
        ParallelAnimation {
            id: panTopCenter
    
            NumberAnimation { target: loaTop; property: "y"; from: 0; to: -480; duration: 250; easing.type: Easing.InOutQuad }
            NumberAnimation { target: loaCenter; property: "y"; from: 480; to: 0; duration: 250; easing.type: Easing.InOutQuad }
        }
    
        // BOTTOM ANIMATIONS
        ParallelAnimation {
            id: panCenterBottom
    
            NumberAnimation { target: loaCenter; property: "y"; from: 0; to: -480; duration: 250; easing.type: Easing.InOutQuad }
            NumberAnimation { target: loaBottom; property: "y"; from: 480; to: 0; duration: 250; easing.type: Easing.InOutQuad }
        }
    
        ParallelAnimation {
            id: panBottomCenter
    
            NumberAnimation { target: loaBottom; property: "y"; from: 0; to: 480; duration: 250; easing.type: Easing.InOutQuad }
            NumberAnimation { target: loaCenter; property: "y"; from: -480; to: 0; duration: 250; easing.type: Easing.InOutQuad }
        }
    
        // LEFT ANIMATIONS
        ParallelAnimation {
            id: panCenterLeft
    
            NumberAnimation { target: loaCenter; property: "x"; from: 0; to: 800; duration: 250; easing.type: Easing.InOutQuad }
            NumberAnimation { target: loaLeft; property: "x"; from: -800; to: 0; duration: 250; easing.type: Easing.InOutQuad }
        }
    
        ParallelAnimation {
            id: panLeftCenter
    
            NumberAnimation { target: loaLeft; property: "x"; from: 0; to: -800; duration: 250; easing.type: Easing.InOutQuad }
            NumberAnimation { target: loaCenter; property: "x"; from: 800; to: 0; duration: 250; easing.type: Easing.InOutQuad }
        }
    
        // RIGHT ANIMATIONS
        ParallelAnimation {
            id: panCenterRight
    
            NumberAnimation { target: loaCenter; property: "x"; from: 0; to: -800; duration: 250; easing.type: Easing.InOutQuad }
            NumberAnimation { target: loaRight; property: "x"; from: 800; to: 0; duration: 250; easing.type: Easing.InOutQuad }
        }
    
        ParallelAnimation {
            id: panRightCenter
    
            NumberAnimation { target: loaRight; property: "x"; from: 0; to: 800; duration: 250; easing.type: Easing.InOutQuad }
            NumberAnimation { target: loaCenter; property: "x"; from: -800; to: 0; duration: 250; easing.type: Easing.InOutQuad }
        }
    }
    
    

    EDIT:

    Well ... after checking the wrong behaviors that the GestureArea I used above caused, because they respond to the click on the onTapAndHold event and I just wanted the answer to the swipe event, I decided to remove them and make a swipe simulation using MouseArea. .

    The swipe action has greatly improved and the click event issue presented by GestureArea has been resolved but has caused the MouseAreas overlay issue.

    This did not exist when using GestureArea as it did not prevent a click on a MouseArea positioned below it and MouseAreas overlap prevents it.

    Anyway, the solution for the GestureArea swipe event I describe below:

    MouseArea {
        anchors.fill: parent
        preventStealing: true
    
        property real reaSpeed: 0.0 // calculates drag speed for swipe to run
        property int intStartY: 0 // starting point pressed by the user's finger
    
        property bool booTracing: false //controls the analyzed drag length
    
        onPressed: {
            intStartY = mouse.y;
    
            reaSpeed = 0;
    
            booTracing = true;
        }
    
        onPositionChanged: {
            if (!booTracing)
            {
                return;
            }
    
            reaSpeed = (intStartY - mouse.y) / 2.0;
    
            if ((reaSpeed > 50) && (mouse.y < (parent.height * 0.2)))
            {
                booTracing = false;
    
                if (booIsShowMenu)
                {
                    sigStartHideMenu();
                }
    
                funSwipeScreens("bottom");
            }
        }
    }
    

    I am checking a way to handle MouseAreas overlay.