QML拖动一个组件,就好像它具有顶层堆叠顺序(最大z) [英] QML drag one component as if it has the top stacking order (largest z)
问题描述
QT5.5,QML:
我正在使用示例
我们设置第三个 Rectangle $ c $的
z
c>到-2,希望它会落后于第一个,但由于它是第二个的孩子,而不是第一个的孩子,它是不可及的。这是拖放示例中发生的情况:项目与祖先相距太远。
要进一步阐述这一点,让我们来看看 DragTile.qml
从拖放
示例,并以类似的方式修改它(这是一个更好的方式来实现同样的事情,顺便说一下):
state:State {
when:mouseArea.drag.active
ParentChange {target:tile; parent:root}
AnchorChanges {target:tile; anchors.verticalCenter:未定义; anchorors.horizontalCenter:undefined}
PropertyChanges {
target:tile
z:100
}
}
这样也不行。要看看发生了什么,我们可以使用一个令人敬畏的小环境变量,名为
为了确保该项目呈现在所有内容之上,您需要将其父对象实际上高于一切的项目。我们可以通过在 tiles.qml
的末尾添加项目
来实现此目的:
项目{
向$ {code> DragTile 组件添加一个属性,赋予代理对容器的访问权限:
id:dragContainer
anchors.fill:parent
}
>
属性项目dragParent
然后,将容器分配到
tiles.qml
中:代理:DragTile {colorKey:red; dragParent:dragContainer}
接下来,修改
父
中的
:ParentChange
的属性DragTile.qmlParentChange {target:tile;父母: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 thirdRectangle
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 theDrag 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 theoverdraw
visualisation, which gives us a nice rotating 3D box containing our scene. Even with ourPropertyChanges
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 oftiles.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 theParentChange
inDragTile.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屋!