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. Keep GridView element in front of others during animation
QtWS25 Last Chance

Keep GridView element in front of others during animation

Scheduled Pinned Locked Moved QML and Qt Quick
7 Posts 3 Posters 2.1k 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.
  • E Offline
    E Offline
    Etchelon
    wrote on last edited by
    #1

    Hello, I'm trying to understand how to maintain an element of a GridView on top of others during a ParentAnimation. I think it's best explained with this snippet, which I beg you to try out:
    @import QtQuick 2.2

    Item {
    width: 400; height: 400
    id: main

    GridView {
    id: grid
    anchors.fill: parent
    cellWidth: width / Math.sqrt(model)
    cellHeight: height / Math.sqrt(model)

    model: 9
    delegate: Rectangle {
    id: rect
    width: grid.cellWidth
    height: grid.cellHeight
    color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)

    Text {
    anchors.centerIn: parent
    text: "ABABAB"
    wrapMode: Text.WrapAtWordBoundaryOrAnywhere
    }

    MouseArea {
    anchors.fill: parent
    onClicked:
    {
    if (rect.state != "fullScreen")
    rect.state = "fullScreen";
    else
    rect.state = "";
    }
    }

    states: [
    State {
    name: "fullScreen"
    ParentChange {
    target: rect
    parent: main
    width: parent.width
    height: parent.height
    x: 0
    y: 0
    }
    }
    ]

    transitions: [
    Transition {
    ParentAnimation {
    NumberAnimation { properties: "x, y, width, height"; duration: 500; easing.type: Easing.InQuad }
    }
    }
    ]
    }
    }
    }
    @
    In practice, I zoom the selected element by changing its parent so that it can extend beyond the cell boundaries. And the zooming-in animation works fine: the rectangle is always painted on top of the others.
    When zooming back though, the first thing that happens is that the parent is changed back to the gridview, therefore the rectangle is painted above previous elements but below the successive ones (in fact, the 1st element, at the top left, is always painted below all other elements whereas the 9th element, at the bottom right, is always painted like I want during the zooming-out animation).

    How can I solve this problem? I came up with a solution but thinking in an imperative way, not in a declarative way like QML requires...

    1 Reply Last reply
    0
    • J Offline
      J Offline
      Jens
      wrote on last edited by
      #2

      Here is one simple way to do it. I introduced a "current" property and declared that if the clicked item is current, its z-order is higher than the other rects. This will ensure that the clicked item is always at the top of the painting stack even when the item is reparented back into the grid.

      @
      Item {
      width: 400; height: 400
      id: main
      property var current
      GridView {
      id: grid
      anchors.fill: parent
      cellWidth: width / Math.sqrt(model)
      cellHeight: height / Math.sqrt(model)

          model: 9
          delegate: Rectangle {
              id: rect
              width: grid.cellWidth
              height: grid.cellHeight
              color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
              z: rect === current ? 100 : 0
      
              Text {
                  anchors.centerIn: parent
                  text: "ABABAB"
                  wrapMode: Text.WrapAtWordBoundaryOrAnywhere
              }
      
              MouseArea {
                  anchors.fill: parent
                  onClicked:
                  {
                      current = rect
                      if (rect.state != "fullScreen")
                          rect.state = "fullScreen";
                      else
                          rect.state = "";
                  }
              }
      
              states: [
                  State {
                      name: "fullScreen"
                      ParentChange {
                          target: rect
                          parent: main
                          width: parent.width
                          height: parent.height
                          x: 0
                          y: 0
                      }
                  }
              ]
      
              transitions: [
                  Transition {
                      ParentAnimation {
                          NumberAnimation { properties: "x, y, width, height"; duration: 500; easing.type: Easing.InQuad  }
                      }
                  }
              ]
          }
      }
      

      }
      @

      1 Reply Last reply
      0
      • O Offline
        O Offline
        onek24
        wrote on last edited by
        #3

        I've got no solution yet but you could try to handle the z-achsis of your delegate. That should work out fine.

        1 Reply Last reply
        0
        • E Offline
          E Offline
          Etchelon
          wrote on last edited by
          #4

          [quote author="Jens" date="1392024205"]Here is one simple way to do it. I introduced a "current" property and declared that if the clicked item is current, its z-order is higher than the other rects. This will ensure that the clicked item is always at the top of the painting stack even when the item is reparented back into the grid.

          @
          Item {
          width: 400; height: 400
          id: main
          property var current
          GridView {
          id: grid
          anchors.fill: parent
          cellWidth: width / Math.sqrt(model)
          cellHeight: height / Math.sqrt(model)

              model: 9
              delegate: Rectangle {
                  id: rect
                  width: grid.cellWidth
                  height: grid.cellHeight
                  color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
                  z: rect === current ? 100 : 0
          
                  Text {
                      anchors.centerIn: parent
                      text: "ABABAB"
                      wrapMode: Text.WrapAtWordBoundaryOrAnywhere
                  }
          
                  MouseArea {
                      anchors.fill: parent
                      onClicked:
                      {
                          current = rect
                          if (rect.state != "fullScreen")
                              rect.state = "fullScreen";
                          else
                              rect.state = "";
                      }
                  }
          
                  states: [
                      State {
                          name: "fullScreen"
                          ParentChange {
                              target: rect
                              parent: main
                              width: parent.width
                              height: parent.height
                              x: 0
                              y: 0
                          }
                      }
                  ]
          
                  transitions: [
                      Transition {
                          ParentAnimation {
                              NumberAnimation { properties: "x, y, width, height"; duration: 500; easing.type: Easing.InQuad  }
                          }
                      }
                  ]
              }
          }
          

          }
          @
          [/quote]

          Thanks Jens, I had indeed previously tried to play with the z coordinate in my main app (the above is just a snippet that somehow follows the structure of the main app), more precisely by giving the Transition an id and setting, inside Rectangle rect, the following:
          @z: transition.running ? 100 : 0@
          This didn't work with my main app but indeed works with the simple example as well as your solution does.
          Maybe the problem is due to the fact that the delegate in my app is actually a Flipable.

          Now, I just came up with the solution: I have to bind the flipable's z with this mechanism to get the result I want!

          This code doesn't work:
          @import QtQuick 2.2

          Item {
          width: 400; height: 400
          id: main

          GridView {
          id: grid
          anchors.fill: parent
          cellWidth: width / Math.sqrt(model)
          cellHeight: height / Math.sqrt(model)

          model: 9
          delegate: Flipable {
          width: grid.cellWidth
          height: grid.cellHeight

          front: Rectangle {
          id: rect
          width: parent.width
          height: parent.height
          z: fullScreenTransition.running ? 100 : 0
          color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)

          Text {
           anchors.centerIn: parent
           text: "ABABAB"
           wrapMode: Text.WrapAtWordBoundaryOrAnywhere
          }
          
          MouseArea {
           anchors.fill: parent
           onClicked:
           {
            if (rect.state != "fullScreen")
             rect.state = "fullScreen";
            else
             rect.state = "";
           }
          }
          
          states: [
           State {
            name: "fullScreen"
            ParentChange {
             target: rect
             parent: main
             width: parent.width
             height: parent.height
             x: 0
             y: 0
            }
           }
          ]
          
          transitions: [
           Transition {
            id: fullScreenTransition
            ParentAnimation {
             NumberAnimation { properties: "x, y, width, height"; duration: 500; easing.type: Easing.InQuad  }
            }
           }
          ]
          

          }
          }
          }
          }
          @

          This code does!
          @import QtQuick 2.2

          Item {
          width: 400; height: 400
          id: main

          GridView {
          id: grid
          anchors.fill: parent
          cellWidth: width / Math.sqrt(model)
          cellHeight: height / Math.sqrt(model)

          model: 9
          delegate: Flipable {
          width: grid.cellWidth
          height: grid.cellHeight
          z: fullScreenTransition.running ? 100 : 0

          front: Rectangle {
          id: rect
          width: parent.width
          height: parent.height

          color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
          
          Text {
           anchors.centerIn: parent
           text: "ABABAB"
           wrapMode: Text.WrapAtWordBoundaryOrAnywhere
          }
          
          MouseArea {
           anchors.fill: parent
           onClicked:
           {
            if (rect.state != "fullScreen")
             rect.state = "fullScreen";
            else
             rect.state = "";
           }
          }
          
          states: [
           State {
            name: "fullScreen"
            ParentChange {
             target: rect
             parent: main
             width: parent.width
             height: parent.height
             x: 0
             y: 0
            }
           }
          ]
          
          transitions: [
           Transition {
            id: fullScreenTransition
            ParentAnimation {
             NumberAnimation { properties: "x, y, width, height"; duration: 500; easing.type: Easing.InQuad  }
            }
           }
          ]
          

          }
          }
          }
          }
          @

          :))

          1 Reply Last reply
          0
          • J Offline
            J Offline
            Jens
            wrote on last edited by
            #5

            It makes sense because z-values are only relevant when comparing items that have the same parent. Since Flippable are all direct children of the GridView, they are painted in order according to the z-value you have set on the Flippable itself.

            When you assign the back or front properties of the Flippable itself, you are actually assigning a child of the flippable, and setting the z-value of a child has no effect on the painting order of its parent. Each node is also drawing all of its children before the next node is considered so the only thing you can effect by setting the z-value of the back item is which order you draw the back vs front Flippable items.

            @
            GridView
            | |
            Delegate1 Delegate2
            | | | |
            Back Front Back Front
            @

            1 Reply Last reply
            0
            • E Offline
              E Offline
              Etchelon
              wrote on last edited by
              #6

              Thanks for the insight Jens! Very interesting :)

              1 Reply Last reply
              0
              • E Offline
                E Offline
                Etchelon
                wrote on last edited by
                #7

                Thanks for the insight Jens! Very interesting :)

                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