Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Activating an animation in an imported (reusable) object
QtWS25 Last Chance

Activating an animation in an imported (reusable) object

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
9 Posts 2 Posters 252 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Mlibu
    wrote on last edited by Mlibu
    #1

    I would like to make a reusable component with an animation, but I would like to activate that animation from the main.qml file. How do I do this?

    main.qml:

    import QtQuick 2.15
    import QtQuick.Window 2.15
    import QtQuick.Controls 2.15
    import "objects"
    
    Window {
        width: 640
        height: 480
        visible: true
        title: qsTr("Hello World")
    
        Column {
            ExpandingRect {
                id: expandingRect
            }
    
            Button {
                text: "change rect"
                onClicked: {
                    expandingRect.animationRect.running = true
                }
            }
        }
    }
    

    objects/ExpandingRect.qml:

    import QtQuick 2.15
    
    Rectangle {
        color: "red"
        height: 50
        width: 50
    
        PropertyAnimation{
            id: animationRect
            target: parent
            property: "width"
            to: if (parent.width == 50) return 200; else return 50
            duration: 500
            easing.type: Easing.InOutQuint
        }
    }
    

    I'm sure it's very simple. Can anyone tell me how to get this to work please?

    Thank you.

    ODБOïO 1 Reply Last reply
    0
    • M Offline
      M Offline
      Mlibu
      wrote on last edited by
      #2

      I would think signals and slots would be a way to solve this? Is that the best or only way?

      1 Reply Last reply
      0
      • M Mlibu

        I would like to make a reusable component with an animation, but I would like to activate that animation from the main.qml file. How do I do this?

        main.qml:

        import QtQuick 2.15
        import QtQuick.Window 2.15
        import QtQuick.Controls 2.15
        import "objects"
        
        Window {
            width: 640
            height: 480
            visible: true
            title: qsTr("Hello World")
        
            Column {
                ExpandingRect {
                    id: expandingRect
                }
        
                Button {
                    text: "change rect"
                    onClicked: {
                        expandingRect.animationRect.running = true
                    }
                }
            }
        }
        

        objects/ExpandingRect.qml:

        import QtQuick 2.15
        
        Rectangle {
            color: "red"
            height: 50
            width: 50
        
            PropertyAnimation{
                id: animationRect
                target: parent
                property: "width"
                to: if (parent.width == 50) return 200; else return 50
                duration: 500
                easing.type: Easing.InOutQuint
            }
        }
        

        I'm sure it's very simple. Can anyone tell me how to get this to work please?

        Thank you.

        ODБOïO Offline
        ODБOïO Offline
        ODБOï
        wrote on last edited by ODБOï
        #3

        hi, in the following code you don't have access to animationRect by id like you are trying

        @Mlibu said in Activating an animation in an imported (reusable) object:

                onClicked: {
                    expandingRect.animationRect.running = true
        

        you can create an alias in ExpandingRect.qml to make the PropertyAnimation object accessible, or have a function that starts the timer

        ///ExpandingRect.qml
        Rectangle {
            property alias animAlias : anim
        // custom function 
           function startAnimation(){
                    anim.start()
                  //... 
                  //...
                }
        
            color: "red"
            height: 50
            width: 50
        
            SequentialAnimation on width {
                  id: anim
                  running: false
                  loops: Animation.Infinite
                  PropertyAnimation { to: 50 }
                  PropertyAnimation { to: 200 }
              }
        }
        
        Window {
            width: 640
            height: 480
            visible: true
         
            Column {
                ExpandingRect {
                    id: expandingRect
                }
        
               Button {
                    text: "change rect"
                    onClicked: {
                        expandingRect.animAlias.running = true // or expandingRect.animAlias.start()
                          
                          // custom function 
                         // expandingRect.startAnimation()
        
                    }
                }
            }
        }
        
        
        1 Reply Last reply
        0
        • M Offline
          M Offline
          Mlibu
          wrote on last edited by Mlibu
          #4

          Ok so I tried both these options, but obviously I am doing something wrong because it's not working. Do I need to use SequentialAnimation instead of PropertyAnimation? It seems the two should be fairly similar. Though I just want to animate once each press but toggle between a width of 50 and 200.

          main.qml:

          import QtQuick 2.15
          import QtQuick.Window 2.15
          import QtQuick.Controls 2.15
          import "objects"
          
          Window {
              width: 640
              height: 480
              visible: true
              title: qsTr("Hello World")
          
              Column {
                  ExpandingRect {
                      id: expandingRect
                  }
          
                  Button {
                      text: "change rect"
                      onClicked: {
                          expandingRect.toggle()
                      }
                  }
              }
          
              Component.onCompleted: {
                  console.log("OUTPUT")
              }
          }
          

          objects/ExtendingRect.qml:

          import QtQuick 2.15
          
          Rectangle {
              id: menuRect
              color: "red"
              height: 50
              width: 50
          
              property alias animationAlias : animationRect
          
              function toggle() {
                  animationAlias.running = true
              }
          
              PropertyAnimation{
                  id: animationRect
                  target: parent
                  property: "width"
                  to: if (parent.width == 50) return 200; else return 50
                  duration: 500
                  easing.type: Easing.InOutQuint
              }
          
              Component.onCompleted: {
              }
          }
          

          I tried it with SequentialAnimation as well but it doesn't work either:
          objects/ExpandingRect.qml:

          import QtQuick 2.15
          
          Rectangle {
              id: menuRect
              color: "red"
              height: 50
              width: 50
          
              property alias animationAlias : animationRect
          
              function toggle() {
                  animationAlias.start()
              }
          
          //    PropertyAnimation{
          //        id: animationRect
          //        target: parent
          //        property: "width"
          //        to: if (parent.width == 50) return 200; else return 50
          //        duration: 500
          //        easing.type: Easing.InOutQuint
          //    }
          
              SequentialAnimation on width {
                        id: animationRect
                        running: false
                        loops: Animation.Infinite
                        PropertyAnimation { to: if (parent.width === 50) return 200; else return 50 }
                        //PropertyAnimation { to: 200 }
                    }
          
              Component.onCompleted: {
              }
          }
          
          ODБOïO 1 Reply Last reply
          0
          • M Mlibu

            Ok so I tried both these options, but obviously I am doing something wrong because it's not working. Do I need to use SequentialAnimation instead of PropertyAnimation? It seems the two should be fairly similar. Though I just want to animate once each press but toggle between a width of 50 and 200.

            main.qml:

            import QtQuick 2.15
            import QtQuick.Window 2.15
            import QtQuick.Controls 2.15
            import "objects"
            
            Window {
                width: 640
                height: 480
                visible: true
                title: qsTr("Hello World")
            
                Column {
                    ExpandingRect {
                        id: expandingRect
                    }
            
                    Button {
                        text: "change rect"
                        onClicked: {
                            expandingRect.toggle()
                        }
                    }
                }
            
                Component.onCompleted: {
                    console.log("OUTPUT")
                }
            }
            

            objects/ExtendingRect.qml:

            import QtQuick 2.15
            
            Rectangle {
                id: menuRect
                color: "red"
                height: 50
                width: 50
            
                property alias animationAlias : animationRect
            
                function toggle() {
                    animationAlias.running = true
                }
            
                PropertyAnimation{
                    id: animationRect
                    target: parent
                    property: "width"
                    to: if (parent.width == 50) return 200; else return 50
                    duration: 500
                    easing.type: Easing.InOutQuint
                }
            
                Component.onCompleted: {
                }
            }
            

            I tried it with SequentialAnimation as well but it doesn't work either:
            objects/ExpandingRect.qml:

            import QtQuick 2.15
            
            Rectangle {
                id: menuRect
                color: "red"
                height: 50
                width: 50
            
                property alias animationAlias : animationRect
            
                function toggle() {
                    animationAlias.start()
                }
            
            //    PropertyAnimation{
            //        id: animationRect
            //        target: parent
            //        property: "width"
            //        to: if (parent.width == 50) return 200; else return 50
            //        duration: 500
            //        easing.type: Easing.InOutQuint
            //    }
            
                SequentialAnimation on width {
                          id: animationRect
                          running: false
                          loops: Animation.Infinite
                          PropertyAnimation { to: if (parent.width === 50) return 200; else return 50 }
                          //PropertyAnimation { to: 200 }
                      }
            
                Component.onCompleted: {
                }
            }
            
            ODБOïO Offline
            ODБOïO Offline
            ODБOï
            wrote on last edited by ODБOï
            #5

            @Mlibu the example i gave u is working, i tested it before i past the code here.
            You do not have to use PropertyAnimation, you can use anything you want
            here is an example with the Behavior QML type

            Rectangle {
                id: rec
                color: "red"
                height: 50
                width: 50
            
                function startAnimation(){
                       if (rec.width <= 50){
                        rec.width = 200
                       }else{
                        rec.width = 50
                       }
                    }
                Behavior on width {NumberAnimation{duration: 500}}
            }
            
            Window {
                width: 640
                height: 480
                visible: true
                title: qsTr("Hello World")
            
                Column {
                    ExpandingRect {
                        id: expandingRect
                    }
            
                    Button {
                        text: "change rect"
                        onClicked: {
                            expandingRect.startAnimation()
                        }
                    }
                }
            }
            

            please note that i used the alias to access an object from the outside (when it is reused somewhere else )
            what you did :

            property alias animationAlias : animationRect
            
                function toggle() {
                    animationAlias.running = true
                }
            
                PropertyAnimation{
                    id: animationRect
            

            is not needed to have an alias, your function can access the PropertyAnimation object directly by id like this

             function toggle() {
                    animationRect.running = true
                }
            
                PropertyAnimation{
                    id: animationRect
            

            your problem comes from this line

            to: if (parent.width == 50) return 200; else return 50
            

            you can verify that just by replacing your javascript if statement by a hardcoded value..

            You can simply use Behavior as i showed

            1 Reply Last reply
            0
            • M Offline
              M Offline
              Mlibu
              wrote on last edited by Mlibu
              #6

              So I cannot use your example directly because I want the animation to extend width to 200 once if the width is 50, or reduce the width to 50 once if the width is 200. It's a toggle to show a menu drawer.

              I made my code exactly as you specified. I used the function method and I also took out the javascript for the to: width and hard coded it to 200. It should extend the square to 200 on the first button press but it is not working. What am I doing wrong here? My impression is that I am following everything you have told me. I think I suspect the use of 'parent' in the PropertyAnimation as the issue. It works if I put it all into main.qml and replace 'parent' with a hard coded ID. But I am not hard coding the ID in the case of a reusable component.

              main.qml:

              import QtQuick 2.15
              import QtQuick.Window 2.15
              import QtQuick.Controls 2.15
              import "objects"
              
              Window {
                  width: 640
                  height: 480
                  visible: true
                  title: qsTr("Hello World")
              
                  Column {
                      ExpandingRect {
                          id: expandingRect
                      }
              
                      Button {
                          text: "change rect"
                          onClicked: {
                              expandingRect.toggle()
                          }
                      }
                  }
              
                  Component.onCompleted: {
                      console.log("OUTPUT")
                  }
              }
              

              objects/ExpandingRect.qml:

              import QtQuick 2.15
              
              Rectangle {
                  color: "red"
                  height: 50
                  width: 50
              
                  function toggle() {
                      animationRect.running = true
                  }
              
                  PropertyAnimation{
                      id: animationRect
                      target: parent
                      property: "width"
                      //to: if (parent.width == 50) return 200; else return 50
                      to: 200
                      duration: 500
                      easing.type: Easing.InOutQuint
                  }
              
                  Component.onCompleted: {
                  }
              }
              
              ODБOïO 1 Reply Last reply
              0
              • M Mlibu

                So I cannot use your example directly because I want the animation to extend width to 200 once if the width is 50, or reduce the width to 50 once if the width is 200. It's a toggle to show a menu drawer.

                I made my code exactly as you specified. I used the function method and I also took out the javascript for the to: width and hard coded it to 200. It should extend the square to 200 on the first button press but it is not working. What am I doing wrong here? My impression is that I am following everything you have told me. I think I suspect the use of 'parent' in the PropertyAnimation as the issue. It works if I put it all into main.qml and replace 'parent' with a hard coded ID. But I am not hard coding the ID in the case of a reusable component.

                main.qml:

                import QtQuick 2.15
                import QtQuick.Window 2.15
                import QtQuick.Controls 2.15
                import "objects"
                
                Window {
                    width: 640
                    height: 480
                    visible: true
                    title: qsTr("Hello World")
                
                    Column {
                        ExpandingRect {
                            id: expandingRect
                        }
                
                        Button {
                            text: "change rect"
                            onClicked: {
                                expandingRect.toggle()
                            }
                        }
                    }
                
                    Component.onCompleted: {
                        console.log("OUTPUT")
                    }
                }
                

                objects/ExpandingRect.qml:

                import QtQuick 2.15
                
                Rectangle {
                    color: "red"
                    height: 50
                    width: 50
                
                    function toggle() {
                        animationRect.running = true
                    }
                
                    PropertyAnimation{
                        id: animationRect
                        target: parent
                        property: "width"
                        //to: if (parent.width == 50) return 200; else return 50
                        to: 200
                        duration: 500
                        easing.type: Easing.InOutQuint
                    }
                
                    Component.onCompleted: {
                    }
                }
                
                ODБOïO Offline
                ODБOïO Offline
                ODБOï
                wrote on last edited by
                #7

                @Mlibu said in Activating an animation in an imported (reusable) object:

                So I cannot use your example directly because I want the animation to extend width to 200 once if the width is 50, or reduce the width to 50 once if the width is 200. It's a toggle to show a menu drawer.

                why not just use Behavior type like in my last example ? it seems like it does exactly what you need

                there is also a ready to use Drawer QML type https://doc.qt.io/qt-6/qml-qtquick-controls2-drawer.html

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  Mlibu
                  wrote on last edited by Mlibu
                  #8

                  The built in drawer QML type cannot reduce to a minimum width to still display icons and have them be selectable as far as I could see. It seemed to be more like a mobile device app drawer than a desktop application drawer. That's why I only reduce width to 50. I will look at the Behavior type. I guess you are saying that PropertyAnimation is not suited to this purpose.

                  Question: To use behavior, you have the id 'rec' defined on the Rectangle, but I want to define the id in main.qml on the definition of ExpandingRectangle. How do I do the startAnimation() with Behavior if there is no id in the object?

                  1 Reply Last reply
                  0
                  • M Offline
                    M Offline
                    Mlibu
                    wrote on last edited by
                    #9

                    I got it to work by giving the rectangle a static id but wrapping it in an Item. I put the toggle function in the item to expose it and set the width and the height of the item to the rectangle width and height so the column would work properly. This way the item gets the id set from main.qml and everything references properly.

                    main.qml:

                    import QtQuick 2.15
                    import QtQuick.Window 2.15
                    import QtQuick.Controls 2.15
                    import "objects"
                    
                    Window {
                        width: 640
                        height: 480
                        visible: true
                        title: qsTr("Hello World")
                    
                        Column {
                            ExpandingRect {
                                id: expandingRect
                            }
                    
                            Button {
                                text: "change rect"
                                onClicked: {
                                    expandingRect.toggle()
                                }
                            }
                        }
                    
                        Component.onCompleted: {
                            console.log("OUTPUT")
                        }
                    }
                    

                    objects/ExpandingRect.qml:

                    import QtQuick 2.15
                    
                    Item {
                        function toggle() {
                            animationRect.running = true
                        }
                        width: leftMenuRect.width
                        height: leftMenuRect.height
                    
                        Rectangle {
                            id: leftMenuRect
                            color: "red"
                            height: 50
                            width: 50
                    
                            PropertyAnimation{
                                id: animationRect
                                target: leftMenuRect
                                property: "width"
                                to: if (leftMenuRect.width == 50) return 200; else return 50
                                //to: 200
                                duration: 500
                                easing.type: Easing.InOutQuint
                            }
                    
                            Component.onCompleted: {
                            }
                        }
                    }
                    
                    1 Reply Last reply
                    0

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved