Reputation: 198
I am not sure if this is a bug in Qt or it's how it should work, but here is a struggle i have:
First, the code that works how i expect it to work:
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" }
}
}
When clicking on a blue rectangle, it gets reparented to a Red rectangle. The console output is:
qml: Parent now is : Item <--- When component created
qml: Parent now is : Red rectangle <--- Reparenting when rectangle was clicked.
I found two cases when reparenting behaves differently. First, if in ParentChange{...}
x
or y
properties are set as a function that returns value:
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" }
}
}
And another case is when there is an Anchor change involved. For example:
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" }
}
}
In both, second and third cases the output is:
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.
Because of this issue, inside of AnchorChanges{}
the value returned for parent.vertical/horizontalCenter
is the Item
when i would expect it to be Red rectangle
So my question is: What could cause this effect, and is this a normal behavior, or it is a bug?
Upvotes: 1
Views: 1079
Reputation: 198
I've found a related bug report, so this question can be closed now.
https://bugreports.qt.io/browse/QTBUG-16727
Edit:
Also, this behavior is described in qt documentation as:
State Fast Forwarding
In order for Transition to correctly animate state changes, it is sometimes necessary for the engine to fast forward and rewind a state (that is, internally set and unset the state) before it is finally applied. The process is as follows:
- The state is fast forwarded to determine the complete set of end values.
- The state is rewound.
- The state is fully applied, with transitions.
In some cases this may cause unintended behavior. For example, a state that changes a view's model or a
Loader's
sourceComponent
will set these properties multiple times (to apply, rewind, and then reapply), which can be relatively expensive.State fast forwarding should be considered an implementation detail, and may change in later versions.
Upvotes: 1