【问题标题】:Qml - How to stop a rectangle dragging outside it's parentQml - 如何停止将矩形拖到其父级之外
【发布时间】:2020-05-05 04:05:29
【问题描述】:

我正在使用 qml 创建一个可调整大小的矩形,该矩形可以拖到它的父窗格内,但不能拖到外面(图 1)。当我调整它的大小时,例如使用左上手柄,它工作得很好,不能在它的父级之外调整大小(图 2)。但是当我拖动整个矩形时,它可以被拖动到其父级之外(图 3)。我的代码尝试对两者使用相同的逻辑,即一旦矩形的左侧到达其父级的左侧,它就会取消拖动。可以很好地调整大小,但是当我拖动矩形时就不行了。我做错了什么?

Pane {
            id: compPane
            implicitHeight: imageListModel.reqViewHeight
            implicitWidth: imageListModel.reqViewWidth
            leftPadding: 0
            topPadding: 0
            clip: true

            background: Rectangle{
                id: backgroundRect
                anchors.fill: parent
                color: "gray"
                border.color: "black"
                border.width: 6
            }

            // Resizable rectangle that can be dragged
            Rectangle {
                id: indRect
                x:parent.width / 4
                y: parent.height / 4
                width: parent.width / 2
                height: parent.width / 2
                border {
                    width: 2
                    color: "steelblue"
                }
                color: "#354682B4"

                MouseArea {
                    id: indImagesDragArea
                    anchors.fill: parent
                    anchors.margins: 8
                    drag.target: parent

                    onPositionChanged: {
                        if (drag.active){
                            if (indRect.x <= 0 + backgroundRect.border.width)
                                Drag.cancel()
                            if (indRect.x + indRect.width >= (compPane.width - backgroundRect.border.width) )
                                Drag.cancel()
                        }
                    }
                }

                // Top Left handle - works well
                Rectangle {
                    width: 15
                    height: 15
                    color: "steelblue"
                    anchors.verticalCenter:parent.top
                    anchors.horizontalCenter: parent.left
                    MouseArea {
                        anchors.fill: parent
                        cursorShape: Qt.SizeFDiagCursor
                        drag{ target: parent; axis: Drag.XAndYAxis }
                        onPositionChanged: {
                            if(drag.active){
                                //var delta = Math.max(mouseX, mouseY)
                                var newWidth = indRect.width - mouseX
                                var newHeight = indRect.height - mouseY;

                                if (newWidth < width || newHeight < height)
                                    return

                                if (indRect.x <= 0 + backgroundRect.border.width && mouseX < 0){
                                    Drag.cancel()
                                    indRect.x =  0 + backgroundRect.border.width
                                }
                                else {
                                    indRect.width = newWidth
                                    indRect.x = indRect.x + mouseX
                                }

                                if (indRect.y <= 0 + backgroundRect.border.width && mouseY < 0){
                                    Drag.cancel()
                                    indRect.y = 0 + backgroundRect.border.width
                                }
                                else{
                                    indRect.height = newHeight
                                    indRect.y = indRect.y + mouseY
                                }
                            }
                        }
                    }
                }
            }
        }

【问题讨论】:

    标签: qt drag-and-drop qml


    【解决方案1】:

    Drag.cancel() 实际上是在实现拖放类型的交互时使用的。在这种情况下,对它的调用什么都不做,因为您实际上从来没有开始这些序列之一。如果您注释掉对 Drag.cancel() 的调用,您的左上句柄示例就可以正常工作。

    为什么您的左上示例有效,是因为您在位置更新上限制 x 和 y,以通过 indRect.xindRect.y 的显式更新将它们剪辑到场景中。您只需要为主要的拖动场景实现相同的技术。

    例如:

    onPositionChanged: {
        if (drag.active){
            if (indRect.x <= 0 + backgroundRect.border.width)
                indRect.x =  0 + backgroundRect.border.width;
            if (indRect.x + indRect.width >= (compPane.width - backgroundRect.border.width) )
                indRect.x = compPane.width - backgroundRect.border.width - indRect.width;
        }
    }
    

    【讨论】:

    • 太棒了!完美的。非常感谢您的宝贵时间。
    【解决方案2】:

    您可以尝试使用drag.minimum 和drag.maximum 的属性。 请参阅文档:

    https://doc.qt.io/qt-5/qml-qtquick-mousearea.html#drag.threshold-prop

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-14
      • 1970-01-01
      相关资源
      最近更新 更多