Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Help with states and transitions



  • I am trying to figure out how to get this Rectangle to move when clicked back, and forth between these two states. What am I doing incorrectly here? Perhaps I don't need a Bool for this?

    import QtQuick 2.12
    import QtQuick.Controls 2.5
    import QtQuick.Window 2.0
    
    ApplicationWindow
    {
      id: root
      visible: true
      width: 640
      height: 480
    
      Rectangle
      {
        id: theRectangle
    
        property bool open: true
    
        height: 75
        width: 150
        anchors.centerIn: parent
        color: "blue"
    
        states: [
          State
          {
            name: "closedState"
            PropertyChanges
            {
              target: theRectangle
              open: false
            }
          },
          State
          {
            name: "openState"
            PropertyChanges
            {
              target: theRectangle
              open: true
            }
          }
        ]
    
        transitions: [
          Transition
          {
            from: "openState"
            to: "closedState"
    
            NumberAnimation
            {
              id: animationClose
              target: theRectangle
              property: "y"
              to: 110
              duration: 1000
            }
    
          },
          Transition
          {
            from: "closedState"
            to: "openState"
    
            NumberAnimation
            {
              id: animationOpen
              target: theRectangle
              property: "y"
              to: 0
              duration: 1000
            }
          }
        ]
    
        MouseArea
        {
          anchors.fill: parent
          onClicked: theRectangle.open ? theRectangle.state = "openState" : theRectangle.state = "closedState"
        }
      }
    }
    
    

  • Qt Champions 2018

    Alternatively you can do it without state, I prefer to avoid state as much as possible, it's too verbose for my linking:

    Rectangle {
        id: theRectangle
        height: 75
        width: 150
        y : open ? 0 : 110
        color: open ? "blue" : "red"
        property bool open: true
        
        Behavior on y {
            NumberAnimation {
                easing.type: Easing.InOutQuad
                duration: 1000
            }
        }
        
        MouseArea {
            anchors.fill: parent
            onClicked: theRectangle.open = !theRectangle.open
        }
    }


  • I have managed to get this working, but I can't seem to get it working using Transitions...

    import QtQuick 2.12
    import QtQuick.Controls 2.5
    import QtQuick.Window 2.0
    
    ApplicationWindow
    {
      id: root
      visible: true
      width: 640
      height: 480
    
      NumberAnimation
      {
        id: animationClose
        target: theRectangle
        property: "y"
        to: 110
        duration: 1000
      }
    
      NumberAnimation
      {
        id: animationOpen
        target: theRectangle
        property: "y"
        to: 0
        duration: 1000
      }
    
      Rectangle
      {
        id: theRectangle
    
        property bool open: true
    
        onOpenChanged: open ? animationOpen.start() : animationClose.start()
    
        height: 75
        width: 150
        color: "blue"
        state: "openState"
    
        states: [
          State
          {
            name: "closedState"
            PropertyChanges
            {
              target: theRectangle
              open: false
            }
          },
          State
          {
            name: "openState"
            PropertyChanges
            {
              target: theRectangle
              open: true
            }
          }
        ]
    
        MouseArea
        {
          anchors.fill: parent
          onClicked: theRectangle.state === "openState" ? theRectangle.state = "closedState" : theRectangle.state = "openState"
        }
      }
    }
    

    Note that I had to bring the NumberAnimation outside of the Rectangle, but I am not sure why.



  • @RobM hi

    there are tons of examples in the docs



  • @LeLev said in Help with states and transitions:

    @RobM hi

    there are tons of examples in the docs

    Yeah, I think I just needed to take a better look at them. I had my Transitions doing the work of States, and States doing the work of the Transitions. This is what I came up with. Not sure if you can think of a way to "trim the fat" so to speak. For instance, can you think of a way for this to be done without the Boolean called "open"?

    import QtQuick 2.12
    import QtQuick.Controls 2.5
    import QtQuick.Window 2.0
    
    ApplicationWindow
    {
      id: root
      visible: true
      width: 640
      height: 480
    
      Rectangle
      {
        id: theRectangle
    
        property bool open: true
    
        height: 75
        width: 150
    
        states: [
          State
          {
            name: "closedState"
            when: theRectangle.open === false
            PropertyChanges
            {
              target: theRectangle
              color: "red"
              y: 110
            }
          },
          State
          {
            name: "openState"
            when: theRectangle.open === true
            PropertyChanges
            {
              target: theRectangle
              color: "blue"
              y: 0
            }
          }
        ]
    
        transitions: Transition 
        {
                NumberAnimation
                {
                  properties: "y"
                  easing.type: Easing.InOutQuad
                  duration: 1000
                }
            }
    
        MouseArea
        {
          anchors.fill: parent
          onClicked: theRectangle.open = !theRectangle.open
        }
      }
    }
    


  • @RobM you can do it witout the bool , just change the state directly in the mouse onClicked
    but i think it is better to keep it like you did

     Rectangle
        {
            id: theRectangle
            height: 75
            width: 150
            y : 0
            color: "blue"
    
            states: [
                State
                {
                    name: "closedState"
                    PropertyChanges
                    {
                        target: theRectangle
                        color: "red"
                        y: 110
                    }
                },
                State
                {
                    name: "openState"
    
                    PropertyChanges
                    {
                        target: theRectangle
                        color: "blue"
                        y: 0
                    }
                }
            ]
    
            transitions: Transition
            {
                NumberAnimation
                {
                    properties: "y"
                    easing.type: Easing.InOutQuad
                    duration: 1000
                }
            }
    
            MouseArea
            {
                anchors.fill: parent
                onClicked:{
                    if(theRectangle.state=== "openState")
                        theRectangle.state = "closedState"
                    else
                        theRectangle.state = "openState"
                }
            }
        }
    

  • Qt Champions 2018

    Alternatively you can do it without state, I prefer to avoid state as much as possible, it's too verbose for my linking:

    Rectangle {
        id: theRectangle
        height: 75
        width: 150
        y : open ? 0 : 110
        color: open ? "blue" : "red"
        property bool open: true
        
        Behavior on y {
            NumberAnimation {
                easing.type: Easing.InOutQuad
                duration: 1000
            }
        }
        
        MouseArea {
            anchors.fill: parent
            onClicked: theRectangle.open = !theRectangle.open
        }
    }


  • @GrecKo Yes your solution is much more clean than mine, thank you.



  • hi,
    Just as a side note, because the original question and title is about Statesand Transitions :

    @RobM said in Help with states and transitions:

    much more clean

    For such simple case, yes, it is clean. But the more properties changes you have the more your qml file will become messy with bindings everywhere and you still might want to use States


  • Qt Champions 2018

    @LeLev said in Help with states and transitions:

    But the more properties changes you have the more your qml file will become messy with bindings everywhere and you still might want to use States

    That hasn't been my experience, if components are independent enough you rarely change more than 3 properties at a time.
    I also don't like the fact that with States you don't directly see in a property binding that it will change, you have to look if there is a State and PropertyChanges somewhere.

    That's the way I see it at least, I won't prevent anybody from using State. I just find it cumbersome and seldom use it.


Log in to reply