我不确定这是Qt中的一个bug,还是它应该如何工作,但我有一个挣扎:
首先,我期望它如何工作的代码:
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{...}中,x或y属性被设置为返回值的函数:
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" }
}
}另一种情况是,有一个锚改变涉及。例如:
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
所以我的问题是:是什么导致了这种影响,这是一种正常的行为,还是一种缺陷?
发布于 2016-11-14 23:28:22
我找到了一个相关的bug报告,所以这个问题现在可以结束了。
https://bugreports.qt.io/browse/QTBUG-16727
编辑:
此外,qt 文档中将此行为描述为:
状态快速转发 为了将状态转换为正确的动态状态更改,有时引擎需要在状态最终应用之前将状态(即内部设置和未设置状态)快速转发和倒转。这一过程如下:
在某些情况下,这可能会导致意外的行为。例如,更改视图的模型或Loader's sourceComponent的状态将多次设置这些属性(用于应用、倒带、然后重新应用),这可能比较昂贵。
状态快速转发应该被视为实现细节,并可能在以后的版本中更改。
https://stackoverflow.com/questions/40584592
复制相似问题