首页 文章

如何在QML中将项目拖动到圆圈内?

提问于
浏览
4

下面的代码允许在一个区域中拖动小的红色矩形,该区域是由最小和最大拖动值定义的矩形 .

我希望它继续直到半径为100的父矩形的边界,这意味着它现在是一个圆 .

如何在QML中将项目拖动到圆圈内?

Window {
    width: 200; height: 200; visible: true

    Rectangle
    {
        x: 10; y: 10
        width: 200; height: 200
        radius: 100
        color: "blue"

        Rectangle {
            x: 10; y: 10
            width: 20; height: 20
            color: "red"

            MouseArea
            {
                id: dragArea
                anchors.fill: parent

                drag.target: parent
                drag.minimumX : 20
                drag.maximumX : 150

                drag.minimumY : 20
                drag.maximumY : 150
            }
        }
    }
}

2 回答

  • 2

    所以我找到了一些时间来提供上述更顺畅的解决方案 .

    import QtQuick 2.5
    import QtQuick.Window 2.2
    
    Window {
        id: root
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        property int radius: 100
    
        Rectangle {
            id: circle
            width: 2 * radius
            height: 2 * radius
            radius: root.radius
    
            color: 'blue'
        }
    
        Rectangle {
            id: mark
            width: 20
            height: 20
            x: (dragObj.dragRadius <= root.radius ? dragObj.x : root.radius + ((dragObj.x - root.radius) * (root.radius / dragObj.dragRadius))) - 10
            y: (dragObj.dragRadius <= root.radius ? dragObj.y : root.radius + ((dragObj.y - root.radius) * (root.radius / dragObj.dragRadius))) - 10
            color: 'red'
    
            MouseArea {
                id: markArea
                anchors.fill: parent
                drag.target: dragObj
                onPressed: {
                    dragObj.x = mark.x + 10
                    dragObj.y = mark.y + 10
                }
            }
        }
    
        Item {
            id: dragObj
            readonly property real dragRadius: Math.sqrt(Math.pow(x - root.radius, 2) + Math.pow(y - root.radius, 2))
            x: root.radius
            y: root.radius
    
            onDragRadiusChanged: console.log(dragRadius)
        }
    }
    

    我使用 dragObj 来避免拖动位置的限制 . 这跨越了圆心的矢量 . 只要 dragObj 本身包含在圆圈中,我将使用它的位置作为标记的位置 .
    但是一旦它离开圆圈,我会将矢量投影到圆上,因此它将保持在极限内 .

    为了确保每次拖动都在标记上再次开始,我将把 dragObj 的位置重置到标记的位置,再次按下鼠标时(新的拖动事件的前提条件)

    玩得开心 .

  • 1

    有点晚了,但我想参加一些测验 .

    这是一个不完美的解决方案,有一些缺陷 .

    import QtQuick 2.5
    import QtQuick.Window 2.2
    
    Window {
        width: 400; height: 400; visible: true
    
        Rectangle
        {
            x: 10; y: 10
            width: 200; height: 200
            radius: 100
            color: "blue"
    
            Rectangle {
                x: 10; y: 10
                width: 20; height: 20
                color: "red"
    
                MouseArea
                {
                    id: dragArea
                    anchors.fill: parent
    
                    drag.target: parent
                    drag.minimumX : Math.ceil(100 - Math.sqrt(200 * parent.y - Math.pow(parent.y, 2)))
                    drag.maximumX : Math.floor(Math.sqrt(200 * parent.y - Math.pow(parent.y, 2)) + 100)
    
                    drag.minimumY : Math.ceil(100 - Math.sqrt(200 * parent.x - Math.pow(parent.x, 2)))
                    drag.maximumY : Math.floor(Math.sqrt(200 * parent.x - Math.pow(parent.x, 2)) + 100)
                }
            }
        }
    }
    

    我们的想法是,根据y和x的当前值计算x和y的最大值和最小值(因此max-x取决于current-y,而max-y取决于current-x)

    其背后的功能是: (r - y)² + (r - x)² = r²

    我没有包含的是小型可拖动矩形的尺寸 . 所以我只强迫左上角保持在圆圈范围内 . 然而,这应该很容易适应 . 为了解释这一点,假设一个圆,一半的矩形宽度/高度减去半径,并将其移动一半的矩形宽度/高度 .

    另一个缺陷是,如果我达到其中一个限制(顶部,左侧,右侧,底部),矩形可能会闪烁并且不会顺利地跟随鼠标 .

    要解决这个问题,您可以使用不可见的对象作为辅助对象,可以自由绘制,然后使用它的位置来计算显示的红色矩形位置 .

    也许我稍后会添加一个实现 . 我很确定,这应该非常顺利 .

相关问题