Aquarius_Girl
Aquarius_Girl

Reputation: 22906

Animate QML Button component

main.qml

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
import QtQuick.Controls 2.1
import QtGraphicalEffects 1.0

Window 
{
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    TT
    {
        MouseArea
        {
            anchors.fill: parent
            onClicked:
            {
                parent.buttonPressed = true
            }
        }
    }
}

TT.qml

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
import QtQuick.Controls 2.1
import QtGraphicalEffects 1.0


Rectangle
{
    id:ll
    height: 20; width: 100

    property bool buttonPressed: false

    Button
    {
        id: redRect
        background: Rectangle
                    {
                        height: 20; width: 100
                        color: "red"
                        border.width: 2
                    }

        anchors.fill: parent

        states: State {
                name: "pressed"; when: ll.buttonPressed
                PropertyChanges { target: redRect; scale: 1.2 ; }
            }

        transitions: Transition
        {
            NumberAnimation { properties: "scale"; duration: 200; easing.type: Easing.InOutQuad }
        }
    }
}

I want to animate the button through main.qml. When I write buttonPressed = true, the problem is that it always stays true.

Where am I supposed to set it to false, so that when I click again, it animates?

Upvotes: 0

Views: 1795

Answers (2)

JarMan
JarMan

Reputation: 8277

This answer works, and it's correct to recommend getting rid of your buttonPressed property and the extraneous MouseArea.

However, here's an alternative solution, because I often find states and transitions hard to follow as code grows and becomes more complicated. A more direct approach is to create animation objects and call them directly.

Button {
    id: redRect
    onPressed: anim.start()

    SequentialAnimation {
        id: anim

        // Expand the button
        PropertyAnimation {
            target: redRect
            property: "scale"
            to: 1.2
            duration: 200
            easing.type: Easing.InOutQuad
        }

        // Shrink back to normal
        PropertyAnimation {
            target: redRect
            property: "scale"
            to: 1.0
            duration: 200
            easing.type: Easing.InOutQuad
        }
    }
}

Upvotes: 4

splaytreez
splaytreez

Reputation: 834

Transition has a property running. You can try something like this:

transitions: Transition
{
    NumberAnimation { 
        properties: "scale";
        duration: 200; 
        easing.type: Easing.InOutQuad
    }

    onRunningChanged: {
        if (!running) buttonPressed = false;
    }
}

Now, do you actually need this property at all? Have you considered using onPressed signal:

Button {
    // ...
    onPressed: {
        state = "pressed"
    }
    // ...
}

This way the state will be changed whenever the button is pressed (as it was before) and you don't need to use the buttonPreessed property.

Upvotes: 1

Related Questions