QML Keep transition during the x seconds on mousearea Pressed once

124 Views Asked by At

I checked the different mouseArea events in the documentation and there is no chance to execute a function while a mouseArea is being pressed once. I want to keep the transition for 5 seconds and after 5 seconds it should out back.

Here is what i'm trying

Rectangle {
    id: bottomBar
    x: 0
    y: 431
    width: 800
    height: 100
    visible: true
    color: "#d0e8f5"
    radius: 32
    border.width: 0
    clip: false

    MouseArea {
        id: mouseArea
        anchors.fill: parent
    }

    states: State {
            name: "moved"; when: mouseArea.pressed
            PropertyChanges { target: bottomBar; x: 0; y: 411}
    }

    transitions: Transition {
        NumberAnimation { properties: "x,y"; easing.type: Easing.InOutQuad; }
    }
}

i want to keep bottomBar on x:0 y:411 for 5 seconds

Thanks to @iam_peter we figured out the solution. I share the solution below. I also added 2 rowlayouts on this bottomBar and wanted to have 4 images with good alignment and i did. Now i want to make this images clickable and bring the ui to another qmls.(i am using stack view for that)

property string initializePage : "MainMenu.qml"
property string lightningPage : "LightningMenu.qml"
property string timerPage : "Timer.qml"

Rectangle {
    id: bottomBar
    x: 0
    y: 431
    width: 800
    height: 100
    visible: true
    color: "#d0e8f5"
    radius: 32
    border.width: 0
    clip: false

    MouseArea {
        id: mouseArea
        anchors.fill: parent
        onPressed: SequentialAnimation {
            PropertyAnimation {
                target: bottomBar
                property: "y"
                to: 411
            }

            PropertyAnimation {
                targets: [bottomRowLeft,bottomRowRight]
                property: "opacity"
                to: 1
            }


            PauseAnimation {
                duration: 5000
            }


            PropertyAnimation {
                targets: [bottomRowLeft,bottomRowRight]
                property: "opacity"
                to: 0
            }


            PropertyAnimation {
                target: bottomBar
                property: "y"
                to: 431
            }


        }
    }
}



RowLayout{
    id: bottomRowLeft
    anchors {
        left: bottomBar.left
        bottom: bottomBar.bottom
    }
    anchors.bottomMargin: 45
    anchors.leftMargin: 175
    spacing: 10
    opacity: 0

    //Home Icon
    Image{
        source: "/images/homeButtonIcon.png"
    }
        MouseArea{
            id: homeClicked
            Layout.fillWidth: true
            onClicked: {
                stackViewTool.replace(Qt.resolvedUrl("MainMenu.qml")) // not working
            }

        }

    Image{
        source:"/images/removeButtonIcon.png"
    }
        MouseArea{
            id: removeClicked
            Layout.fillWidth: true
        }
}

RowLayout{
    id: bottomRowRight
    anchors {
        left: bottomRowLeft.right
        bottom: bottomBar.bottom
    }
    anchors.bottomMargin: 45
    anchors.leftMargin: 215
    spacing: 10
    opacity: 0

    //Home Icon
    Image{
        source: "/images/cancelButtonIcon.png"
    }
        MouseArea{
            id: cancelClicked
            Layout.fillWidth: true
        }

    Image{
        source:"/images/applyButtonIcon.png"
    }
        MouseArea{
            id: applyClicked
            Layout.fillWidth: true
            onClicked: {
                stackViewTool.replace(lightningPage)
            }
        }
}


StackView {
    id: stackViewTool
    anchors {
        left: parent.left
        right: parent.right
        top: parent.top
        bottom: bottomBar.top
    }
    initialItem: initializePage

}
3

There are 3 best solutions below

1
On BEST ANSWER

You want to trigger an animation on MouseArea press, then the property should change, pause and go back to the previous value?

Rectangle {
    id: bottomBar
    x: 0
    y: 431
    width: 800
    height: 100
    visible: true
    color: "#d0e8f5"
    radius: 32
    border.width: 0
    clip: false

    MouseArea {
        id: mouseArea
        anchors.fill: parent
        onPressed: SequentialAnimation {
            PropertyAnimation {
                target: bottomBar
                property: "y"
                to: 411
            }
            PauseAnimation {
                duration: 5000
            }
            PropertyAnimation {
                target: bottomBar
                property: "y"
                to: 431
            }
        }
    }
}
2
On

I made the following changes to your example:

  • Use a Page control
  • Put the toolbar in the footer section
  • Use Frame and RowLayout for the toolbar
  • Refactored AppButton.qml for a clickable icon Button
  • Supplied mock MainPage.qml and LightningPage.qml
  • Supply mock SVG assets
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Page {
    StackView {
        id: stackView
        anchors.fill: parent
        initialItem: "MainPage.qml"
    }
    footer: Frame {
        background: Rectangle { color: "#d0e8f5" }
        RowLayout {
            AppButton {
                icon.source: "home-32.svg"
                onClicked: stackView.replace("MainPage.qml")
            }
            AppButton {
                icon.source: "x-circle-32.svg"
            }
            AppButton {
                icon.source: "thumbs-up-32.svg"
                onClicked: stackView.replace("LightningPage.qml")
            }
        }
    }
}

// MainPage.qml
import QtQuick
import QtQuick.Controls

Page {
    Text {
        anchors.centerIn: parent
        text: qsTr("MainPage.qml")
    }
}

// LightningPage.qml
import QtQuick
import QtQuick.Controls

Page {
    Text {
        anchors.centerIn: parent
        text: qsTr("LightningPage.qml")
    }
}

// AppButton.qml
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Button {
    Layout.preferredWidth: 64
    Layout.preferredHeight: 64
    background: Rectangle {
        radius: 8
        border.color: focused ? pressed ? "white" : "black" : "grey"
        color: pressed ? "lightsteelblue" : "#ccc"
    }
    icon.color: pressed ? "white" : "black"
    icon.width: 32
    icon.height: 32
}

// home-32.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M11 8.5V5H6v8.5L2.5 17H5v12h8v-8h6v8h8V17h2.5L16 3.5zM26 16v12h-6v-8h-8v8H6V16H4.914L7 13.914V6h3v4.914l6-6L27.086 16z"/><path fill="none" d="M0 0h32v32H0z"/></svg>

// thumbs-up-32.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M29.878 13.966A2.564 2.564 0 0 0 27.422 12h-4.61a12.784 12.784 0 0 1-1.447-.054 4.48 4.48 0 0 1 .078-.083c.063-.051 1.522-1.33 1.522-4.903 0-2.832-.52-4.436-1.591-4.904a2.336 2.336 0 0 0-2.283.577l-.16.148L18.93 3a9.143 9.143 0 0 1-1.608 4.53 12.855 12.855 0 0 1-3.396 3.745L10.78 16H9v-2H3v15h6v-2h2.767l3.363 2h9.664a2.807 2.807 0 0 0 2.534-1.58 2.586 2.586 0 0 0 .069-2.196 2.683 2.683 0 0 0 1.464-1.773 2.773 2.773 0 0 0-.42-2.298 2.873 2.873 0 0 0 1.303-1.938 2.754 2.754 0 0 0-.653-2.22 3.037 3.037 0 0 0 .787-3.03zM8 28H4V15h4zm20.073-11.477l-.582.364.525.442a1.889 1.889 0 0 1 .74 1.73 2.006 2.006 0 0 1-1.299 1.487l-.748.305.605.533a1.786 1.786 0 0 1 .58 1.814 1.725 1.725 0 0 1-1.342 1.261l-.776.167.485.628a1.589 1.589 0 0 1 .17 1.725A1.813 1.813 0 0 1 24.794 28h-9.389l-3.363-2H9v-9h2.32l3.255-4.96a13.852 13.852 0 0 0 3.58-3.957 10.348 10.348 0 0 0 1.764-4.833 1.222 1.222 0 0 1 1.055-.278c.298.13.99.78.99 3.988 0 3.06-1.16 4.135-1.197 4.169-.194.193-.705.706-.483 1.244.25.599 1.037.627 2.528.627h4.61a1.58 1.58 0 0 1 1.495 1.241 1.99 1.99 0 0 1-.844 2.282z"/><path fill="none" d="M0 0h32v32H0z"/></svg>

// x-circle-32.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M22.864 10.843L17.207 16.5l5.657 5.657-.707.707-5.657-5.657-5.657 5.657-.707-.707 5.657-5.657-5.657-5.657.707-.707 5.657 5.657 5.657-5.657zM29.8 16.5A13.3 13.3 0 1 1 16.5 3.2a13.3 13.3 0 0 1 13.3 13.3zm-1 0a12.3 12.3 0 1 0-12.3 12.3 12.314 12.314 0 0 0 12.3-12.3z"/><path fill="none" d="M0 0h32v32H0z"/></svg>

You can Try it Online!

1
On

The issue on your example is that the MouseArea isn't filling the Image you should use anchors.fill and make the MouseArea a child of the Image. Currently it is also layouted by the RowLayout which you might want but doesn't make sense if you want to make the images button-like. I came up with this solution which might be what you want. This is just a guess.

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts

Window {
    id: root

    color: "white"
    width: 800
    height: 600
    visible: true

    component SimplePage: Rectangle {
        property alias name: pageText.text
        width: root.width
        height: 200
        color: "lightgrey"

        Text {
            id: pageText
            anchors.centerIn: parent
            font.pixelSize: 40
        }
    }

    component SimpleButton: Rectangle {
        property alias letter: buttonText.text
        signal clicked

        color: "grey"
        width: 40
        height: 40

        Text {
            id: buttonText
            anchors.centerIn: parent
            font {
                pixelSize: 20
                bold: true
            }
        }

        MouseArea {
            anchors.fill: parent
            onClicked: parent.clicked()
        }
    }

    Component {
        id: initializePage

        SimplePage { name: "initialize" }
    }

    Component {
        id: lightningPage

        SimplePage { name: "lightning" }
    }

    Component {
        id: timerPage

        SimplePage { name: "timer" }
    }

    Rectangle {
        id: bottomBar
        x: 0
        y: 431
        width: 800
        height: 100
        visible: true
        color: "#d0e8f5"
        radius: 32
        border.width: 0
        clip: false

        MouseArea {
            id: mouseArea
            anchors.fill: parent
            onPressed: SequentialAnimation {
                PropertyAnimation {
                    target: bottomBar
                    property: "y"
                    to: 411
                }

                PropertyAnimation {
                    targets: [bottomRowLeft,bottomRowRight]
                    property: "opacity"
                    to: 1
                }

                PauseAnimation {
                    duration: 5000
                }

                PropertyAnimation {
                    targets: [bottomRowLeft,bottomRowRight]
                    property: "opacity"
                    to: 0
                }

                PropertyAnimation {
                    target: bottomBar
                    property: "y"
                    to: 431
                }
            }
        }
    }

    RowLayout {
        id: bottomRowLeft
        anchors {
            left: bottomBar.left
            bottom: bottomBar.bottom
        }
        anchors.bottomMargin: 45
        anchors.leftMargin: 175
        spacing: 10
        opacity: 0

        // Home
        SimpleButton {
            letter: "H"
            onClicked: stackViewTool.replace(initializePage)
        }
        // Remove
        SimpleButton {
            letter: "R"
        }
    }

    RowLayout {
        id: bottomRowRight
        anchors {
            left: bottomRowLeft.right
            bottom: bottomBar.bottom
        }
        anchors.bottomMargin: 45
        anchors.leftMargin: 215
        spacing: 10
        opacity: 0

        // Cancel
        SimpleButton {
            letter: "C"
        }
        // Apply
        SimpleButton {
            letter: "A"
            onClicked: stackViewTool.replace(lightningPage)
        }
    }

    StackView {
        id: stackViewTool
        anchors {
            left: parent.left
            right: parent.right
            top: parent.top
            bottom: bottomBar.top
        }
        initialItem: initializePage
    }
}