QML 拖动一个组件,就好像它具有顶部堆叠顺序(最大 z) [英] QML drag one component as if it has the top stacking order (largest z)
问题描述
QT5.5,QML:
我正在使用示例
我们将第三个 Rectangle
的 z
值设置为 -2,希望它会落后于第一个,但因为它是第二个的子代而不是第一,遥不可及.这就是拖放示例中发生的情况:项目在祖先方面相距太远.
为了进一步说明这一点,让我们以 Drag and Drop
示例中的 DragTile.qml
为例,并以与您类似的方式对其进行修改(这是一种更好的顺便说一句,实现同样的事情):
状态:状态 {何时:mouseArea.drag.activeParentChange {目标:平铺;父:根}AnchorChanges {目标:平铺;anchors.verticalCenter:未定义;anchors.horizontalCenter: 未定义 }属性变化 {目标:瓷砖z: 100}}
这也行不通.要查看发生了什么,我们可以使用一个很棒的小环境变量,名为
为确保该项目呈现在所有内容之上,您需要将其作为父项,使其成为实际上高于所有内容的项目.我们可以通过在 tiles.qml
的末尾添加一个 Item
来做到这一点:
项目{id: 拖拽容器anchors.fill:父级}
向 DragTile
组件添加一个属性,使代理能够访问容器:
属性项dragParent
然后,在tiles.qml
中分配容器:
delegate: DragTile { colorKey: "red";拖动父级:dragContainer }
接下来,修改DragTile.qml
中ParentChange
的parent
属性:
ParentChange { 目标:平铺;父:dragParent }
最终结果:
请注意,我有意排除了后退"按钮,但如果您出于某种原因也想让它超过该按钮,您可以将 dragContainer
移到层次结构的更高位置.
QT5.5, QML:
I am using the example "Qt Quick Examples - Drag and Drop" In this example, you could see that if we drag the red tile "1", it appears under other tiles when we drag it.
I don't like this effect since when we drag one item, I hope it always appears on the top of whole GUI.
What I tried is: Once the mouse is pressed, we set the item's z as the largest value. And when the mouse is released, set the z to the small value (or better we could save the original value and reset it back to its original valule)
MouseArea {
id: mouseArea
width: 64; height: 64
anchors.centerIn: parent
drag.target: tile
onPressed: {
tile.z = 100;
}
onReleased: {
tile.z = 0;
parent = tile.Drag.target !== null ? tile.Drag.target : root
}
}
But the code does not work. Actually by using console.log, I could see the z value changes, but the dragging ghost image still appears at the bottom. So I guess when onPressed is implemented, the drag mechanism has used its original z value and gets no chance to access the updated z value.
So any idea to have a more decent drag movement?
Thanks!
The z
value of items only applies to siblings and the immediate (direct) parent:
Items with a higher stacking value are drawn on top of siblings with a lower stacking order. Items with the same stacking value are drawn bottom up in the order they appear. Items with a negative stacking value are drawn under their parent's content.
Let's use a small example to test the parent/child scenario:
import QtQuick 2.3
import QtQuick.Window 2.0
Window {
visible: true
width: 200
height: 200
title: qsTr("Hello World")
flags: Qt.FramelessWindowHint
Rectangle {
color: "salmon"
width: 64
height: 64
anchors.centerIn: parent
Text {
text: "1"
}
Rectangle {
color: "steelblue"
x: 32
y: 32
width: 64
height: 64
Text {
text: "2"
}
Rectangle {
color: "orchid"
x: 16
y: -16
width: 64
height: 64
z: -2
Text {
text: "3"
}
}
}
}
}
We set the z
value of the third Rectangle
to -2, hoping that it would go behind the first one, but since it's a child of the second and not the first, it's out of reach. This is what's happening in the drag and drop example: the items are too far apart in terms of ancestory.
To elaborate further on this, let's take DragTile.qml
from the Drag and Drop
example and modify it in a similar way to yours (this is a nicer way of achieving the same thing, by the way):
states: State {
when: mouseArea.drag.active
ParentChange { target: tile; parent: root }
AnchorChanges { target: tile; anchors.verticalCenter: undefined; anchors.horizontalCenter: undefined }
PropertyChanges {
target: tile
z: 100
}
}
This also won't work. To see what's going on, we can use an awesome little environment variable called QSG_VISUALIZE
. Specifically, we want to use the overdraw
visualisation, which gives us a nice rotating 3D box containing our scene. Even with our PropertyChanges
above, you can see that the stacking order of the item is unchanged:
To ensure that the item is rendered on top of everything, you need to parent it to an item that is actually above everything. We can do this by adding an Item
to the end of tiles.qml
:
Item {
id: dragContainer
anchors.fill: parent
}
Add a property to the DragTile
component that gives the delegate access to the container:
property Item dragParent
Then, assign the container in tiles.qml
:
delegate: DragTile { colorKey: "red"; dragParent: dragContainer }
Next, modify the parent
property of the ParentChange
in DragTile.qml
:
ParentChange { target: tile; parent: dragParent }
The end result:
Note that I intentionally excluded the "back" button, but if you wanted to make it go above that as well for some reason, you can just move dragContainer
higher up the hierarchy.
这篇关于QML 拖动一个组件,就好像它具有顶部堆叠顺序(最大 z)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!