Fundido de entrada/salida en Qt/QML

 C Programming >> Programación C >  >> Tags >> Qt
Fundido de entrada/salida en Qt/QML

Esta guía le muestra cómo agregar un efecto de aparición/desaparición gradual a un control en QML. Hay muchas animaciones integradas en Qt/QML, pero no aparecen o desaparecen gradualmente. Usando una máquina de estado y un SequentialAnimation , primero podemos animar la opacidad, luego establecer la visibilidad, logrando un efecto de fundido de entrada/salida. Otras formas como un PropertyAnimation también están disponibles pero son menos expresivos o configurables.

El visibility propiedad de un elemento no se puede animar directamente, ya que es un bool . Por lo tanto, tenemos que animar el opacity propiedad, que es un número de 0.0 a 1.0. Usando un NumberAnimation da control sobre la duración y los coloca en un SequentialAnimation hace que sucedan en orden. Al combinar eso con la máquina de estado integrada que tiene cada control QML (para invertir el orden de los efectos al ocultar el elemento), logramos un fundido de entrada/salida bien animado, sin tener que escribir código OpenGL personalizado en C++ para nuestro propio control QML.

Aquí hay un GIF que muestra el efecto completo y también cómo se ve cuando solo cambias la visibilidad:

¿Es esto complicado? Sí, creo que sí, una máquina de estado completa para solo un efecto de desvanecimiento/desvanecimiento. ¿Es bueno que Qt/QML les permita hackear esto juntos usando su biblioteca estándar integrada? Sí, creo que sí. ¿Preferiría tener un efecto que pueda simplemente aplicar, como, por ejemplo, uno de los efectos de desenfoque incorporados? Sí, eso sería aún mejor. Otras animaciones y efectos son fáciles de hacer, así que ¿por qué no agregar uno integrado para este efecto?

Aparición/desaparición gradual de QML

Agregue la siguiente máquina de estado y transiciones a su control QML, luego vincule el estado a una propiedad o actívelo directamente. El id del control es exampleControl y la propiedad que utilizo para activar la animación de aparición/desaparición gradual se llama folded .

id: exampleControl
property bool folded: false
state: !folded ? "Visible" : "Invisible"
states: [
    State{
        name: "Visible"
        PropertyChanges{target: exampleControl; opacity: 1.0}
        PropertyChanges{target: exampleControl; visible: true}
    },
    State{
        name:"Invisible"
        PropertyChanges{target: exampleControl; opacity: 0.0}
        PropertyChanges{target: exampleControl; visible: false}
    }
]

transitions: [
    Transition {
        from: "Visible"
        to: "Invisible"

        SequentialAnimation{
            NumberAnimation {
                target: exampleControl
                property: "opacity"
                duration: 500
                easing.type: Easing.InOutQuad
            }
            NumberAnimation {
                target: exampleControl
                property: "visible"
                duration: 0
            }
        }
    },

    Transition {
        from: "Invisible"
        to: "Visible"
        SequentialAnimation{
            NumberAnimation {
                target: exampleControl
                property: "visible"
                duration: 0
            }
            NumberAnimation {
                target: exampleControl
                property: "opacity"
                duration: 500
                easing.type: Easing.InOutQuad
            }
        }
    }
]

Código fuente de ejemplo completo

Este es el código que crea el GIF grabado en el artículo. Muestra el código de animación y cómo vincularlo a una propiedad que se puede activar. Encontré el ejemplo de la máquina de estado en stackoverflow, pero ya no puedo encontrar el tema específico en el historial de mi navegador, por lo que no puedo vincular al ejemplo de origen. Si lo sabe, envíeme un correo electrónico para que pueda actualizar este artículo.

import QtQuick 2.15
import QtQuick.Controls 1.4
import QtQuick.Window 2.15

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Fade in / Fade out demo by raymii.org")

    Column {
        anchors.fill: parent
        anchors.margins: 20
        spacing: 20

        Row {
            spacing: 20
            Button {
                text: fadeRect.folded ? "Fade in" : "Fade out"
                onClicked: fadeRect.folded = !fadeRect.folded
            }

            Button {
                text: toggleRect.visible ? "Hide" : "Show"
                onClicked: toggleRect.visible = !toggleRect.visible
            }

        }

        Rectangle {
            id: fadeRect
            width: 410
            height: 60
            border.width: 3
            property bool folded: true
            border.color: "#cccccc"
            color: "#efefef"

            Row {
                anchors.fill: parent
                anchors.margins: 10
                spacing: 5

                Button {
                    text: "Button 1"
                }
                Button {
                    text: "Button 2"
                }
                Button {
                    text: "Button 3"
                }
            }


            state: !folded ? "Visible" : "Invisible"
            states: [
                State{
                    name: "Visible"
                    PropertyChanges{target: fadeRect; opacity: 1.0}
                    PropertyChanges{target: fadeRect; visible: true}
                },
                State{
                    name:"Invisible"
                    PropertyChanges{target: fadeRect; opacity: 0.0}
                    PropertyChanges{target: fadeRect; visible: false}
                }
            ]

            transitions: [
                Transition {
                    from: "Visible"
                    to: "Invisible"

                    SequentialAnimation{
                        NumberAnimation {
                            target: fadeRect
                            property: "opacity"
                            duration: 500
                            easing.type: Easing.InOutQuad
                        }
                        NumberAnimation {
                            target: fadeRect
                            property: "visible"
                            duration: 0
                        }
                    }
                },

                Transition {
                    from: "Invisible"
                    to: "Visible"
                    SequentialAnimation{
                        NumberAnimation {
                            target: fadeRect
                            property: "visible"
                            duration: 0
                        }
                        NumberAnimation {
                            target: fadeRect
                            property: "opacity"
                            duration: 500
                            easing.type: Easing.InOutQuad
                        }
                    }
                }
            ]

        }


        Rectangle {
            id: toggleRect
            width: 410
            height: 60
            border.color: "#cccccc"
            color: "#efefef"
            border.width: 3
            visible: false

            Row {
                anchors.fill: parent
                anchors.margins: 10
                spacing: 5

                Button {
                    text: "Button 1"
                }
                Button {
                    text: "Button 2"
                }
                Button {
                    text: "Button 3"
                }
            }
        }
    }
}