QML ParentChange过渡动画问题

时间:2016-11-14 08:32:06

标签: qt qml

我不确定这是否是Qt中的错误或者它应该如何工作,但这是我的奋斗:

首先,代码可以解释我的工作方式:

import QtQuick 2.3
import QtQuick.Window 2.2

  Item {

      width: 200; height: 100
      objectName: "Item"

      Rectangle {
          id: redRect
          objectName: "Red rectangle"
          width: 100; height: 100
          color: "red"
      }

      Rectangle {
          id: blueRect
          objectName: "Blue rectangle"
          x: redRect.width
          width: 50; height: 50
          color: "blue"

          property bool selected: false

          states: State {
              when: blueRect.selected
              name: "reparented"
              ParentChange {
                  target: blueRect
                  parent: redRect
                  width: 10
                  height: 10
              }
          }

          transitions: [
              Transition {
                  from: "*"
                  to: "reparented"

                  ParallelAnimation{
                      ParentAnimation{
                          NumberAnimation{
                              properties: "width, height"
                              duration: 400
                          }
                      }
                      }
                  }
          ]

          onParentChanged: console.log("Parent now is :", parent.objectName)

          MouseArea { anchors.fill: parent; onClicked: blueRect.selected = !blueRect.selected}//blueRect.state = "reparented" }
      }
  }

单击蓝色矩形时,会将其重新设置为红色矩形。控制台输出是:

qml: Parent now is : Item   <--- When component created
qml: Parent now is : Red rectangle   <--- Reparenting when rectangle was clicked.

我发现两种情况,重新表现的行为不同。首先,如果将ParentChange{...} xy属性设置为返回值的函数:

import QtQuick 2.3
import QtQuick.Window 2.2

  Item {

      width: 200; height: 100
      objectName: "Item"

      Rectangle {
          id: redRect
          objectName: "Red rectangle"
          width: 100; height: 100
          color: "red"
      }

      Rectangle {
          id: blueRect
          objectName: "Blue rectangle"
          x: redRect.width
          width: 50; height: 50
          color: "blue"

          property bool selected: false

          function someFunc() {return 10} // <------ add this line

          states: State {
              when: blueRect.selected
              name: "reparented"
              ParentChange {
                  target: blueRect
                  parent: redRect
                  width: someFunc()    // <--- change here
                  height: someFunc()   // <--- chaghe here
              }
          }

          transitions: [
              Transition {
                  from: "*"
                  to: "reparented"

                  ParallelAnimation{
                      ParentAnimation{
                          NumberAnimation{
                              properties: "width, height"
                              duration: 400
                          }
                      }
                      }
                  }
          ]

          onParentChanged: console.log("Parent now is :", parent.objectName)

          MouseArea { anchors.fill: parent; onClicked: blueRect.selected = !blueRect.selected}//blueRect.state = "reparented" }
      }
  }

另一个案例是涉及到Anchor变更的时候。例如:

import QtQuick 2.3
import QtQuick.Window 2.2

  Item {

      width: 200; height: 100
      objectName: "Item"

      Rectangle {
          id: redRect
          objectName: "Red rectangle"
          width: 100; height: 100
          color: "red"
      }

      Rectangle {
          id: blueRect
          objectName: "Blue rectangle"
          x: redRect.width
          width: 50; height: 50
          color: "blue"

          property bool selected: false

          states: State {
              when: blueRect.selected
              name: "reparented"
              ParentChange {
                  target: blueRect
                  parent: redRect
                  width: 10
                  height: 10
              }
              AnchorChanges {
                  target: blueRect
                  anchors.horizontalCenter: parent.horizontalCenter
                  anchors.verticalCenter: parent.verticalCenter
              }
          }

          transitions: [
              Transition {
                  from: "*"
                  to: "reparented"

                  ParallelAnimation{
                      ParentAnimation{
                          NumberAnimation{
                              properties: "width, height"
                              duration: 400
                          }
                      }
                      AnchorAnimation {
                          duration: 400
                      }
                      }
                  }
          ]

          onParentChanged: console.log("Parent now is :", parent.objectName)

          MouseArea { anchors.fill: parent; onClicked: blueRect.selected = !blueRect.selected}//blueRect.state = "reparented" }
      }
  }

在第二和第三种情况下,输出为:

qml: Parent now is : Item   <--- When component is created
qml: Parent now is : Red rectangle   <--- Here is after blue rectangle is clicked
qml: Parent now is : Item   <--- Now this is where it gets glitchy. Blue rectangle gets reparented back to Item
qml: Parent now is : Red rectangle   <--- And now it gets reparented to a Red rectangle back, as i would expect.

由于此问题,在AnchorChanges{}内,parent.vertical/horizontalCenter返回的值是Item,当我预期它为Red rectangle

所以我的问题是:什么可能导致这种影响,这是一种正常的行为,还是一个错误?

1 个答案:

答案 0 :(得分:1)

我发现了一个相关的错误报告,所以现在可以关闭这个问题了。

https://bugreports.qt.io/browse/QTBUG-16727

修改

此外,此行为在qt documentation中描述为:

  

州快速转发

     

为了使Transition能够正确地为状态更改设置动画,它就是   有时需要发动机快进和倒回状态   (最后,在内部设置和取消设置状态)   应用。过程如下:

     
      
  1. 快速转发状态以确定完整的结束值集。
  2.   
  3. 国家倒闭了。
  4.   
  5. 状态已完全应用,具有过渡。
  6.         

    在某些情况下,这可能会导致意外行为。例如,一个州   更改视图模型或Loader's sourceComponent将设置   这些属性多次(应用,倒带,然后重新应用),   这可能相对昂贵。

         

    应将状态快速转发视为实施细节,   并且可能会在以后的版本中发生变化。