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. Animation between images
Forum Updated to NodeBB v4.3 + New Features

Animation between images

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
6 Posts 2 Posters 2.4k Views 1 Watching
  • 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
    metRo_
    wrote on last edited by
    #1

    Hello,

    I have a little qml that show an image based on some events from c++ backend. I created some states and for each state I have have set the properties for every single image to obtain the effect I want.

    But my qml code looks ugly. I want simple as active image slide to left while at the same time next image to show slide from right side (800px) to left (0px)

    I have read QML Repeater but it doesn't accept an array of image objects.

    How would you do that? I have tried also to set the target an image object but it doesn't seem to work.

    Can you point me some steps?

    Thank you

    import QtQuick 2.4
    import QtQuick.Window 2.2
    
    Window {
        visible: true
        width: 800; height: 480
    
        Rectangle {
            id: page
            state: msg.author
            width: 800; height: 480
            color: "#FEDC32"
    
            Text {
                id: tutorial
                z: 100
                width: 100; height: 100
                text: msg.author    // invokes Message::author() to get this value
    
                Component.onCompleted: {
                    msg.author = "Jonah"  // invokes Message::setAuthor()
                }
    
                function teste(){
                    msg.author = "teste2"
                }
            }
    
            Text {
                id: tutorial2
                z: 100
                y: 50
                width: 100; height: 100
                text: msg.debug    // invokes Message::author() to get this value
            }
    
            states: [
                // This adds a second state to the container where the rectangle is farther to the right
    
                State { name: "quarto"
                    PropertyChanges {
                        target: quartoImage
                        x: 0
                    }
                    PropertyChanges {
                        target: mainImage
                        x: -800
                    }
                    PropertyChanges {
                        target: salaImage
                        x: -800
                    }
                    PropertyChanges {
                        target: escImage
                        x: -800
                    }
                },
                State { name: "sala"
                    PropertyChanges {
                        target: salaImage
                        x: 0
                    }
                    PropertyChanges {
                        target: quartoImage
                        x: 800
                    }
                    PropertyChanges {
                        target: mainImage
                        x: 800
                    }
                    PropertyChanges {
                        target: escImage
                        x: -800
                    }
                },
                State { name: "main"
                    PropertyChanges {
                        target: quartoImage
                        x: 800
                    }
                    PropertyChanges {
                        target: salaImage
                        x: -800
                    }
                    PropertyChanges {
                        target: mainImage
                        x: 0
                    }
                    PropertyChanges {
                        target: escImage
                        x: -800
                    }
                },
                State { name: "esc"
                    PropertyChanges {
                        target: quartoImage
                        x: 800
                    }
                    PropertyChanges {
                        target: salaImage
                        x: -800
                    }
                    PropertyChanges {
                        target: mainImage
                        x: 800
                    }
                    PropertyChanges {
                        target: escImage
                        x: 0
                    }
                }
            ]
    
            transitions: [
                Transition {
                    from: "main"; to: "quarto";// reversible: true
                    ParallelAnimation {
                        NumberAnimation { properties: "x"; duration: 500; easing.type: Easing.InOutQuad }
                        ColorAnimation { duration: 500 }
                    }
                },
                Transition {
                    from: "quarto"; to: "main";// reversible: true
                    ParallelAnimation {
                        NumberAnimation { properties: "x"; duration: 500; easing.type: Easing.InOutQuad }
                        ColorAnimation { duration: 500 }
                    }
                },
                Transition {
                    from: "main"; to: "sala";// reversible: true
                    ParallelAnimation {
                        NumberAnimation { properties: "x"; duration: 500; easing.type: Easing.InOutQuad }
                        ColorAnimation { duration: 500 }
                    }
                },
                Transition {
                    from: "sala"; to: "main";// reversible: true
                    ParallelAnimation {
                        NumberAnimation { properties: "x"; duration: 500; easing.type: Easing.InOutQuad }
                        ColorAnimation { duration: 500 }
                    }
                },
                Transition {
                    from: "main"; to: "esc";// reversible: true
                    ParallelAnimation {
                        NumberAnimation { properties: "x"; duration: 500; easing.type: Easing.InOutQuad }
                        ColorAnimation { duration: 500 }
                    }
                },
                Transition {
                    from: "esc"; to: "main";// reversible: true
                    ParallelAnimation {
                        NumberAnimation { properties: "x"; duration: 500; easing.type: Easing.InOutQuad }
                        ColorAnimation { duration: 500 }
                    }
                }
    
            ]
    
            MouseArea {
                x: 0
                y: 0
                width: 399;
                height: 480;
                onClicked: { console.log(page.state+"->"); page.state = "sala"; console.log(page.state) }
            }
    
            MouseArea {
                x: 401
                y: 0
                width: 399;
                height: 480;
                onClicked: { console.log(page.state+"->"); page.state = "quarto"; console.log(page.state) }
            }
    
            Image {
                id: mainImage
                source: "qrc:/ikea.jpg"
                anchors.verticalCenter: page.verticalCenter
            }
    
            Image {
                id: salaImage
                source: "qrc:/sala.jpg"
                anchors.verticalCenter: page.verticalCenter
    
                MouseArea {
                    anchors.fill: parent;
                    onClicked: { console.log();console.log(page.state+"->"); page.state = "main"; console.log(page.state) }
                }
            }
    
            Image {
                id: quartoImage
                source: "qrc:/quarto.jpg"
    
                MouseArea {
                    anchors.fill: parent;
                    onClicked: { console.log(page.state+"->"); page.state = "main"; console.log(page.state) }
                }
            }
    
            Image {
                id: escImage
                source: "qrc:/esc.jpg"
    
                MouseArea {
                    anchors.fill: parent;
                    onClicked: { console.log(page.state+"->"); page.state = "main"; console.log(page.state) }
                }
            }
    
        }
    
    }
    
    
    1 Reply Last reply
    0
    • D Offline
      D Offline
      devel
      wrote on last edited by
      #2

      Use ListView to show a list of images.

      import QtQuick 2.4
      
      Item {
      	id: root
      
      	ListView {
      		anchors.fill: parent
      
      		orientation: ListView.Horizontal // content will move horizontally when scrolling
      		snapMode: ListView.SnapOneItem // scrolling won't stop at the middle of an image
      		interactive: false // is not scrollable with mouse or keyboard arrows
      
      		delegate: Item {
      			width: root.width // if the image is smaller than the window, the next image will be still out of the screen
      
      			Image {
      				source: modelData
      			}
      		}
      
      		model: [
      			"1.jpeg",
      			"2.jpeg",
      			"3.jpeg",
      			"4.jpeg",
      			"5.jpeg"
      		]
      
      		MouseArea {
      			anchors.fill: parent
      			onClicked: parent.currentIndex += 1 // scroll to next when clicked
      		}
      	}
      }
      
      M 1 Reply Last reply
      1
      • D devel

        Use ListView to show a list of images.

        import QtQuick 2.4
        
        Item {
        	id: root
        
        	ListView {
        		anchors.fill: parent
        
        		orientation: ListView.Horizontal // content will move horizontally when scrolling
        		snapMode: ListView.SnapOneItem // scrolling won't stop at the middle of an image
        		interactive: false // is not scrollable with mouse or keyboard arrows
        
        		delegate: Item {
        			width: root.width // if the image is smaller than the window, the next image will be still out of the screen
        
        			Image {
        				source: modelData
        			}
        		}
        
        		model: [
        			"1.jpeg",
        			"2.jpeg",
        			"3.jpeg",
        			"4.jpeg",
        			"5.jpeg"
        		]
        
        		MouseArea {
        			anchors.fill: parent
        			onClicked: parent.currentIndex += 1 // scroll to next when clicked
        		}
        	}
        }
        
        M Offline
        M Offline
        metRo_
        wrote on last edited by
        #3

        @devel Thank you for the example :)
        However I want to be able to change from 1.jpg to 3.jpg per example. So all the images that aren't on center should be ready to show.

        1 Reply Last reply
        0
        • D Offline
          D Offline
          devel
          wrote on last edited by devel
          #4

          A bit hacky solution with Path. I'm not sure that PathView guarantees exact positioning of the elements. Maybe it's time to go back to the PropertyAnimations that you were doing before.

          import QtQuick 2.4
          
          Item {
          	id: root
          
          	PathView {
          		anchors.fill: parent
          
          		interactive: false
          
          		model: 2 // will hold 2 empty images
          
          		delegate: Item {
          			width: root.width
          
          			property alias source: img.source
          
          			Image {
          				id: img
          			}
          		}
          
          		path: Path {
          			startX: root.width * 1.5 // starting point is the middle of the imaginary screen on the right (center of the next Item is here)
          			startY: 0
          			PathLine { x: -root.width * 0.5; y: 0 } // destination point is the middle of the imaginary screen on the left (center of the current item will slide to here)
          		}
          
          		MouseArea {
          			anchors.fill: parent
          			onClicked: {
          				parent.currentIndex += 1
          				parent.currentItem.source = "4.jpeg"
          			}
          		}
          	}
          }
          

          Also, to see what's really going on, I've added some coloured rectangles. Launch the next code with QSG_VISUALIZE=overdraw environment variable to see the stuff that's outside the window.

          Command line:

          $ QSG_VISUALIZE=overdraw qmlscene path.qml
          

          Code (almost the same):

          import QtQuick 2.4
          
          Item {
          	id: root
          
          	PathView {
          		anchors.fill: parent
          
          		interactive: false
          
          		model: 2 // will hold 2 empty images
          
          		delegate: Rectangle {
          			height: 50
          			color: ["red","blue"][modelData]
          
          			width: root.width
          
          			property alias source: img.source
          
          			Image {
          				id: img
          			}
          		}
          
          		path: Path {
          			startX: root.width * 1.5 // starting point is the middle of the imaginary screen on the right (center of the next Item is here)
          			startY: 0
          			PathLine { x: -root.width * 0.5; y: 0 } // destination point is the middle of the imaginary screen on the left (center of the current item eill slide to here)
          		}
          
          		MouseArea {
          			anchors.fill: parent
          			onClicked: {
          				parent.currentIndex += 1
          				parent.currentItem.source = "4.jpeg"
          			}
          		}
          	}
          }
          
          M 1 Reply Last reply
          0
          • D devel

            A bit hacky solution with Path. I'm not sure that PathView guarantees exact positioning of the elements. Maybe it's time to go back to the PropertyAnimations that you were doing before.

            import QtQuick 2.4
            
            Item {
            	id: root
            
            	PathView {
            		anchors.fill: parent
            
            		interactive: false
            
            		model: 2 // will hold 2 empty images
            
            		delegate: Item {
            			width: root.width
            
            			property alias source: img.source
            
            			Image {
            				id: img
            			}
            		}
            
            		path: Path {
            			startX: root.width * 1.5 // starting point is the middle of the imaginary screen on the right (center of the next Item is here)
            			startY: 0
            			PathLine { x: -root.width * 0.5; y: 0 } // destination point is the middle of the imaginary screen on the left (center of the current item will slide to here)
            		}
            
            		MouseArea {
            			anchors.fill: parent
            			onClicked: {
            				parent.currentIndex += 1
            				parent.currentItem.source = "4.jpeg"
            			}
            		}
            	}
            }
            

            Also, to see what's really going on, I've added some coloured rectangles. Launch the next code with QSG_VISUALIZE=overdraw environment variable to see the stuff that's outside the window.

            Command line:

            $ QSG_VISUALIZE=overdraw qmlscene path.qml
            

            Code (almost the same):

            import QtQuick 2.4
            
            Item {
            	id: root
            
            	PathView {
            		anchors.fill: parent
            
            		interactive: false
            
            		model: 2 // will hold 2 empty images
            
            		delegate: Rectangle {
            			height: 50
            			color: ["red","blue"][modelData]
            
            			width: root.width
            
            			property alias source: img.source
            
            			Image {
            				id: img
            			}
            		}
            
            		path: Path {
            			startX: root.width * 1.5 // starting point is the middle of the imaginary screen on the right (center of the next Item is here)
            			startY: 0
            			PathLine { x: -root.width * 0.5; y: 0 } // destination point is the middle of the imaginary screen on the left (center of the current item eill slide to here)
            		}
            
            		MouseArea {
            			anchors.fill: parent
            			onClicked: {
            				parent.currentIndex += 1
            				parent.currentItem.source = "4.jpeg"
            			}
            		}
            	}
            }
            
            M Offline
            M Offline
            metRo_
            wrote on last edited by
            #5

            @devel I understand the idea. Now I'm trying to set the next image from C++. I was looking on how to change the model from c++ ( http://doc.qt.io/qt-5/qtquick-modelviewsdata-cppmodels.html ) but after the PathView is created any changes on the model from C++ doesn't take any action on QML :s

            1 Reply Last reply
            0
            • D Offline
              D Offline
              devel
              wrote on last edited by devel
              #6

              The model-view is when we give all images to ListView/PathView (or something like that) and then let user to manipulate them.

              The last example with PathView isn't a real model-view. It's a hack to show just one image and to be able to change it with a sliding effect.

              It's possible to control the image via a property like that for example:

              import QtQuick 2.4
              
              Item {
                  id: root
              
                  property url imageSource
              
                  onImageSourceChanged: {
                      pathView.currentIndex += 1
                      pathView.currentItem.source = imageSource
                  }
              
                  PathView {
                      id: pathView
              
                      anchors.fill: parent
              
                  ...
              

              C++ can definitively bind something different to this new imageSource property.

              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