user-interface - QML 拖动一个组件,就好像它具有顶部堆叠顺序(最大 z)

标签 user-interface drag-and-drop qml

QT5.5、QML:

我正在使用示例“Qt Quick Examples - Drag and Drop
在此示例中,您可以看到,如果我们拖动红色瓷砖“1”,当我们拖动它时,它会出现在其他瓷砖下方。

我不喜欢这种效果,因为当我们拖动一个项目时,我希望它总是出现在整个 GUI 的顶部。

我尝试的是:
按下鼠标后,我们将项目的 z 设置为最大值。释放鼠标时,将 z 设置为较小的值(或者更好的是我们可以保存原始值并将其重置为原始值)

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
        }
}

但是代码不起作用。
实际上通过使用console.log,我可以看到z值发生了变化,但拖拽的幽灵图像仍然出现在底部。
所以我猜想当 onPressed 被实现时,拖拽机制已经使用了它原来的 z 值并且没有机会访问更新的 z 值。

那么有什么想法可以进行更体面的拖动运动吗?

谢谢!

最佳答案

z items 的值仅适用于 sibling 和直接(直接) 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.



我们用一个小例子来测试一下父子场景:
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"
                }
            }
        }
    }
}

stacking order

我们设置z第三个值 Rectangle到-2,希望它会落后于第一个,但由于它是第二个而不是第一个的 child ,所以它遥不可及。这就是拖放示例中发生的情况:项目在祖先方面相距太远。

为了进一步详细说明,让我们以 DragTile.qml来自 Drag and Drop示例并以与您类似的方式对其进行修改(顺便说一句,这是实现相同目标的更好方法):
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
    }
}

这也行不通。要查看发生了什么,我们可以使用一个很棒的小环境变量 QSG_VISUALIZE .具体来说,我们想使用 overdraw 可视化,它为我们提供了一个包含场景的漂亮旋转 3D 框。即使使用我们的 PropertyChanges上图,可以看到item的堆叠顺序没有改变:

stacking order overdraw visualisation

为确保该项目呈现在所有内容之上,您需要将其作为实际上高于所有内容的项目的父级。我们可以通过添加 Item 来做到这一点到tiles.qml结尾:
Item {
    id: dragContainer
    anchors.fill: parent
}

将属性添加到 DragTile让代理访问容器的组件:
property Item dragParent

然后,分配 tiles.qml 中的容器:
delegate: DragTile { colorKey: "red"; dragParent: dragContainer }

接下来修改parent ParentChange 的属性(property)在 DragTile.qml :
ParentChange { target: tile; parent: dragParent }

最终结果:

stacking order correct visualisation

请注意,我有意排除了“返回”按钮,但如果您出于某种原因也想让它超过该按钮,您可以移动 dragContainer更高的层次结构。

关于user-interface - QML 拖动一个组件,就好像它具有顶部堆叠顺序(最大 z),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32533105/

相关文章:

java - 幸运游戏 GUI.. 怎么了?

Android 在应用程序之间拖放

qt - 如何改变 "Qt Quick - Control 2 RoundButton"的颜色

c++ - 如果在宏中使用,qmlRegisterType 模板将失败

javascript - 当我拖动一个元素时,react-sortable-hoc 列表消失

qt - 减少 Qml 路径 View 成员之间的距离

javascript - 在 jQuery UI 中触发鼠标拖动

android - 将框/列与屏幕底部对齐 Jetpack Compose

java - 如何在Java中将多个扩展JPanel添加到一个JFrame中?

jquery - 将静态列表 <ul> 中的项目 <li> 替换为来自可排序列表 <ul> 的拖动项目 <li>