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. Combining ParentChange with AnchorChanges
Forum Updated to NodeBB v4.3 + New Features

Combining ParentChange with AnchorChanges

Scheduled Pinned Locked Moved QML and Qt Quick
9 Posts 2 Posters 2.5k 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
    maxus
    wrote on 10 Apr 2013, 10:27 last edited by
    #1

    I'm trying to change parent and anchor at the same time, while animating the anchor change (Qt 5.0.1, Windows):

    @import QtQuick 2.0

    Item {
    id: topItem
    width: 200; height: 200

    Rectangle {
        id: redRect
        width: 100; height: 100
        x: 20
        y: 20
        color: "red"
    }
    
    Rectangle {
        id: blueRect
        width: 50; height: 50
        color: "blue"
        anchors { top: redRect.top; left: redRect.right }
    
        states: State {
            name: "reparented"
            AnchorChanges   { target: blueRect; anchors.left: redRect.left; }
            ParentChange    { target: blueRect; parent: redRect; }
        }
    
        transitions: Transition {
            ParentAnimation { via: topItem }
            AnchorAnimation { duration: 1000 }
        }
    
        MouseArea {
            anchors.fill: parent;
            onClicked: blueRect.state = "reparented"
        }
    }
    

    }@

    The blue box doesn't move to the new position immediately, but jumps to the right first, then moves to the proper position according to the animation; removing ParentAnimation { via: topItem } doesn't fix anything.

    I'm doing it because ParentAnimation is limited to x,y animation only, but I want to change the parent as well. If I try to change the parent afterwords, it doesn't work either:

    @Item {
    id: topItem
    width: 200; height: 200

    Rectangle {
        id: redRect
        width: 100; height: 100
        x: 20
        y: 20
        color: "red"
    }
    
    Rectangle {
        id: blueRect
        width: 50; height: 50
        color: "blue"
        anchors { top: redRect.top; left: redRect.right }
    
        states: State {
            name: "reparented"
            AnchorChanges   { target: blueRect; anchors.left: redRect.left; }
        }
    
        transitions: Transition {
            SequentialAnimation{
                AnchorAnimation { duration: 1000 }
                ScriptAction{ script: blueRect.parent = redRect }
            }
        }
    
        MouseArea {
            anchors.fill: parent;
            onClicked: blueRect.state = "reparented"
        }
    }
    

    }@

    After a correct animation the blue box jumps down. If I remove ScriptAction{ script: blueRect.parent = redRect } it works as expected, but the parent is not changed then.

    I would like to ask if it is a bug or am I doing something wrong? And how should I actually do it correctly?

    1 Reply Last reply
    0
    • M Offline
      M Offline
      melghawi
      wrote on 16 Apr 2013, 00:22 last edited by
      #2

      Try flipping the state changes around. That worked for me.

      @
      import QtQuick 2.0

      Item {
      id: topItem
      width: 200; height: 200

          Rectangle {
                  id: redRect
                  width: 100; height: 100
                  x: 20
                  y: 20
                  color: "red"
          }
      
          Rectangle {
                  id: blueRect
                  width: 50; height: 50
                  color: "blue"
                  anchors { top: redRect.top; left: redRect.right }
      
                  states: State {
                          name: "reparented"
                          ParentChange { target: blueRect; parent: redRect; }
                          AnchorChanges { target: blueRect; anchors.left: redRect.left; }                        
                  }
      
                  transitions: Transition {
                          ParentAnimation { via: topItem }
                          AnchorAnimation { duration: 1000 }
                  }
      
                  MouseArea {
                          anchors.fill: parent;
                          onClicked: blueRect.state = "reparented"
                  }
          }
      

      }
      @

      1 Reply Last reply
      0
      • M Offline
        M Offline
        maxus
        wrote on 16 Apr 2013, 08:43 last edited by
        #3

        Thanks moeg687. Your code indeed works, but now there is another problem: if I enable clipping on the redRectangle, changing parent via topItem doesn't work, the blueRectangle is still being clipped against the red one:

        @import QtQuick 2.0

        Item {
        id: topItem
        width: 200; height: 200

            Rectangle {
                    id: redRect
                    width: 100; height: 100
                    clip: true
                    x: 20
                    y: 20
                    color: "red"
            }
        
            Rectangle {
                    id: blueRect
                    width: 50; height: 50
                    color: "blue"
                    anchors { top: redRect.top; left: redRect.right }
        
                    states: State {
                            name: "reparented"
                            ParentChange { target: blueRect; parent: redRect; }
                            AnchorChanges { target: blueRect; anchors.left: redRect.left; }
                    }
        
                    transitions: Transition {
                            ParentAnimation { via: topItem }
                            AnchorAnimation { duration: 1000 }
                    }
        
                    MouseArea {
                            anchors.fill: parent;
                            onClicked: blueRect.state = "reparented"
                   }
            }
        

        }@

        1 Reply Last reply
        0
        • M Offline
          M Offline
          melghawi
          wrote on 17 Apr 2013, 10:47 last edited by
          #4

          This is as close as I can get it. It seems that the blueRect is anchoring to the topItem when animating and then snapping back to it's correct position.

          @
          Item {
          id: topItem
          width: 200; height: 200

          Rectangle {
              id: redRect
              width: 100; height: 100
              clip: true
              x: 20;
              y: 20
              color: "red"        
          }
          
          Rectangle {
              id: blueRect        
              width: 50; height: 50
              color: "blue"
              anchors { top: redRect.top; left: redRect.right }
          
              states: State {
                  name: "reparented"
                  ParentChange { target: blueRect; parent: redRect }
                  AnchorChanges{ target: blueRect; anchors.left: redRect.left }
              }
          
              transitions: Transition {
                  ParentAnimation { via: topItem
                      AnchorAnimation { duration: 1000 }
                  }
              }
          
              MouseArea {
                  anchors.fill: parent
                  onClicked: blueRect.state = "reparented"
              }
          }
          

          }
          @

          I even tried changing the parent after the anchor change using a timer but that seemed to mess up the blueRect's position. I'm not quite sure what's happening here. Could be a bug.

          Does your project absolutely require anchors?

          @
          Item {
          id: topItem
          width: 200; height: 200

          Rectangle {
              id: redRect
              width: 100; height: 100
              clip: true
              x: 20;
              y: 20
              color: "red"
          }
          
          Rectangle {
              id: blueRect
              width: 50; height: 50
              color: "blue"
              x: redRect.x + redRect.width
              y: redRect.y
          
              states: State {
                  name: "reparented"
                  ParentChange { target: blueRect; parent: redRect; x: 0 }
              }
          
              transitions: Transition {
                  ParentAnimation { via: topItem
                      NumberAnimation { property: "x"; duration: 1000 }
                  }
              }
          
              MouseArea {
                  anchors.fill: parent
                  onClicked: blueRect.state = "reparented"
              }
          }
          

          }
          @

          1 Reply Last reply
          0
          • M Offline
            M Offline
            maxus
            wrote on 17 Apr 2013, 11:15 last edited by
            #5

            Your last code sample works, since it uses the built-in properties of ParentChange - "x" and "y", and your solution is probably as good as it can be at the moment.

            What I was concerned about is that using anchors seems much cleaner, than setting "x" and "y", especially if I want to draw something in the middle of something else, where it becomes really kinda ugly x: parent.x + parent.width/2 - width/2. But what can we do... I will probably just avoid using re-parenting =)

            ps: I've opened a bug report: "QTBUG-30723":https://bugreports.qt-project.org/browse/QTBUG-30723

            1 Reply Last reply
            0
            • M Offline
              M Offline
              melghawi
              wrote on 17 Apr 2013, 22:43 last edited by
              #6

              Yeah anchoring is much cleaner. You can still use anchoring. It is the re-parenting that seems to ruin the object's position. Is there any reason why you need to re-parent the object in the first place?

              1 Reply Last reply
              0
              • M Offline
                M Offline
                maxus
                wrote on 18 Apr 2013, 09:07 last edited by
                #7

                Honestly, while trying to figure out how to work it out, I forgot why I needed re-parenting in the first place =)

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  maxus
                  wrote on 19 Apr 2013, 09:04 last edited by
                  #8

                  From the bug report's comments I understood, that the logic behind all this is the following: while items are static they store relative x/y coordinates, so the blueRect has x/y relative to the topItem; when ParentChange happens Qt simply changes the scene graph by changing the parent of blueRect to the redRect. The x/y coordinates now become relative to the redRect, and since anchors are not reevaluated at the ParentChange jump occurs.

                  It just came to me now, as I realized that only y coordinate snaps, how to solve it: We have to specify all anchors again in the AnchorChanges! Here is the solution/workaround to the problem:

                  @
                  Item {
                  id: topItem
                  width: 200; height: 200

                  Rectangle {
                      id: redRect
                      clip: true
                      width: 100; height: 100
                      x: 20
                      y: 20
                      color: "red"
                  }
                  
                  Rectangle {
                      id: blueRect
                      width: 50; height: 50
                      color: "blue"
                      anchors { top: redRect.top; left: redRect.right }
                  
                      states: State {
                          name: "reparented"
                          AnchorChanges {
                              target: blueRect;
                              anchors.left: redRect.left
                              anchors.top:  redRect.top
                          }
                      }
                  
                      transitions: Transition {
                          SequentialAnimation{
                              AnchorAnimation { duration: 1000 }
                              ScriptAction{ script: blueRect.parent = redRect }
                          }
                      }
                  
                      MouseArea {
                          anchors.fill: parent;
                          onClicked: blueRect.state = "reparented"
                      }
                  }
                  

                  }
                  @

                  I've opened a suggestion "QTBUG-30772":https://bugreports.qt-project.org/browse/QTBUG-30772 to fix this issue.

                  1 Reply Last reply
                  0
                  • M Offline
                    M Offline
                    melghawi
                    wrote on 19 Apr 2013, 09:42 last edited by
                    #9

                    Thanks maxus for posting your find! It makes sense now.

                    1 Reply Last reply
                    0

                    2/9

                    16 Apr 2013, 00:22

                    topic:navigator.unread, 7
                    • Login

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