QML拖动一个组件,就好像它具有顶层堆叠顺序(最大z) [英] QML drag one component as if it has the top stacking order (largest z)

查看:1119
本文介绍了QML拖动一个组件,就好像它具有顶层堆叠顺序(最大z)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

QT5.5,QML:



我正在使用示例



我们设置第三个 Rectangle z c>到-2,希望它会落后于第一个,但由于它是第二个的孩子,而不是第一个的孩子,它是不可及的。这是拖放示例中发生的情况:项目与祖先相距太远。



要进一步阐述这一点,让我们来看看 DragTile.qml 拖放示例,并以类似的方式修改它(这是一个更好的方式来实现同样的事情,顺便说一下):

  state:State {
when:mouseArea.drag.active
ParentChange {target:tile; parent:root}
AnchorChanges {target:tile; anchors.verticalCenter:未定义; anchorors.horizo​​ntalCenter:undefined}
PropertyChanges {
target:tile
z:100
}
}

这样也不行。要看看发生了什么,我们可以使用一个令人敬畏的小环境变量,名为



为了确保该项目呈现在所有内容之上,您需要将其父对象实际上高于一切的项目。我们可以通过在 tiles.qml 的末尾添加项目来实现此目的:

 项目{
id:dragContainer
anchors.fill:parent
}
向$ {code> DragTile 组件添加一个属性,赋予代理对容器的访问权限:


>

 属性项目dragParent 

然后,将容器分配到 tiles.qml 中:

 代理:DragTile {colorKey:red; dragParent:dragContainer} 

接下来,修改 中的 ParentChange 的属性DragTile.qml

  ParentChange {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 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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆