【问题标题】:Conditional drag and drop in QMLQML 中的条件拖放
【发布时间】:2021-04-01 11:05:25
【问题描述】:

此代码生成两个放置区域和一个可拖动的蓝色矩形。
我希望只能将蓝色矩形放置在金色放置区域中。另一个放置区域应该拒绝接受这个特定的矩形。

我可以写什么来实现这一点?

因此,在这段代码中,颜色为“gold”的 DropArea 具有键“xyz”,我已将 Drag.keys: "xyz" 设置为应该被拖动的蓝色矩形。

现在,那个蓝色矩形在另一个放置区域中被排除在外,但在金色区域中却没有。

我做错了什么?

import QtQuick 2.4
import QtQuick.Window 2.2

Window {
    id: win
    width: 800
    height: 600
    title: "Drag & drop example"
    visible: true

    Repeater {
        model: 1
        Rectangle {
            id: rect
            width: 50
            height: 50
            z: mouseArea.drag.active ||  mouseArea.pressed ? 2 : 1
            color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
            x: Math.random() * (win.width / 2 - 100)
            y: Math.random() * (win.height - 100)
            property point beginDrag
            property bool caught: false
            border { width:2; color: "white" }
            radius: 5
            Drag.active: mouseArea.drag.active

            Text {
                anchors.centerIn: parent
                text: index
                color: "white"
            }
            MouseArea {
                id: mouseArea
                anchors.fill: parent
                drag.target: parent
                Drag.keys: "xyz"
                onPressed: {
                    rect.beginDrag = Qt.point(rect.x, rect.y);
                }
                onReleased: {
                    if(!rect.caught) {
                        backAnimX.from = rect.x;
                        backAnimX.to = beginDrag.x;
                        backAnimY.from = rect.y;
                        backAnimY.to = beginDrag.y;
                        backAnim.start()
                    }
                }

            }
            ParallelAnimation {
                id: backAnim
                SpringAnimation { id: backAnimX; target: rect; property: "x"; duration: 500; spring: 2; damping: 0.2 }
                SpringAnimation { id: backAnimY; target: rect; property: "y"; duration: 500; spring: 2; damping: 0.2 }
            }
        }
    }

    Rectangle
    {
        x: 0; y: 0
        width: 200
        height: 200
        color: "gold"
        DropArea {
            anchors.fill: parent
            keys: "xyz"
            onEntered: drag.source.caught = true;
            onExited: drag.source.caught = false;
        }
    }

    Rectangle
    {
        x: 0; y: 300
        width: 200
        height: 200
        color: "red"
        DropArea {
            anchors.fill: parent
            keys: "abc"
            onEntered: drag.source.caught = true;
            onExited: drag.source.caught = false;
        }
    }
}

【问题讨论】:

    标签: qt qml


    【解决方案1】:

    我尝试了您的代码,发现您做错了什么。您将Drag.keys 设置在错误的位置。不要将其设置在MouseArea 中,而是将其设置在被拖动的对象中。

            Rectangle {
                id: rect
                ...
                Drag.active: mouseArea.drag.active
                Drag.keys: "xyz"
    
                MouseArea {
                    id: mouseArea
                    anchors.fill: parent
                    drag.target: parent
                    ...
                }
            }
    

    【讨论】:

    • 我们不应该在 droparea 中也设置键吗?它如何知道接受哪些密钥?
    • 是的,保持你的那部分代码不变。只需更改放置 Drag.keys 的位置即可。
    【解决方案2】:

    您应该使用DropArea 和相关类中的keys 属性。如 Qt 文档中所述,这用作拖放事件的过滤器

    ...
    
    Rectangle { 
        Drag.keys: "gold" //only allow drag to gold
        MouseArea {
            id: mouseArea
            anchors.fill: parent
            drag.target: parent
            onPressed: {
                rect.beginDrag = Qt.point(rect.x, rect.y);
            }
            ...
        }
    }
    
    ...
    
    Rectangle
    {
        x: 0; y: 0
        width: 200
        height: 200
        color: "gold"
        DropArea {
            anchors.fill: parent
            keys: "gold"
            onEntered: drag.source.caught = true;
            onExited: drag.source.caught = false;
        }
    }
    
    Rectangle
    {
        x: 0; y: 300
        width: 200
        height: 200
        color: "red"
        DropArea {
            anchors.fill: parent
            keys: "red"
            onEntered: drag.source.caught = true;
            onExited: drag.source.caught = false;
        }
    }
    

    您不应该省略红色矩形的键,否则它将接受所有拖动源。


    此外,如果您希望接受多个来源,您可以指定一个键列表:

    DropArea {
        keys: ["gold", "nuggets", "at", "the", "end", "of", "a", "rainbow"]
    }
    

    拖动源也是如此:

    Drag.keys: ["gold", "bar", "in", "the", "back"]
    

    【讨论】:

    • 谢谢。我已经编辑了这个问题。我请求你帮助我。
    • @Aquarius_Girl 我也编辑了我的答案
    • 我的理解是,在拖放区域中应该接受键拖动“xyz”,键为“xyz”。我编辑的代码拒绝这样做。我无法找出问题所在。
    • 查看 JarMan 的答案,我也更新了我的问题(顺便说一句,您可能不应该编辑原始问题中的更新部分)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-09
    相关资源
    最近更新 更多