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

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

问题描述

QT5.5,QML:

我正在使用示例

我们将第三个 Rectanglez 值设置为 -2,希望它会落后于第一个,但因为它是第二个的子代而不是第一,遥不可及.这就是拖放示例中发生的情况:项目在祖先方面相距太远.

为了进一步说明这一点,让我们以 Drag and Drop 示例中的 DragTile.qml 为例,并以与您类似的方式对其进行修改(这是一种更好的顺便说一句,实现同样的事情):

状态:状态 {何时:mouseArea.drag.activeParentChange {目标:平铺;父:根}AnchorChanges {目标:平铺;anchors.verticalCenter:未定义;anchors.horizo​​ntalCenter: 未定义 }属性变化 {目标:瓷砖z: 100}}

这也行不通.要查看发生了什么,我们可以使用一个很棒的小环境变量,名为

为确保该项目呈现在所有内容之上,您需要将其作为父项,使其成为实际上高于所有内容的项目.我们可以通过在 tiles.qml 的末尾添加一个 Item 来做到这一点:

项目{id: 拖拽容器anchors.fill:父级}

DragTile 组件添加一个属性,使代理能够访问容器:

属性项dragParent

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

delegate: DragTile { colorKey: "red";拖动父级:dragContainer }

接下来,修改DragTile.qmlParentChangeparent属性:

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

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