Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Getting binding loop when checking mousearea.containsMouse on a drag operation



  • I cannot tell why I am getting a binding loop here.

    main.qml:

    import QtQuick 2.12
    import QtQuick.Window 2.12
    
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Dragon Drop: drag to window")
    
        ColorAnimation on color {
            id: rejectAnimation
    
            running: false
            from: "#FCC"
            to: "#EEE"
            duration: 1000
        }
    
        DropArea {
            id: dropArea
            anchors.fill: parent
            keys: ["amet/displaykey"]
            onEntered: (drag) => {
                if(drag.proposedAction != Qt.CopyAction){
                    drag.accepted = false
                    rejectAnimation.start()
                }
            }
            onDropped: (drop) => {
                var textdata = drop.getDataAsString(keys[0])
                if (textdata.length) {
                    if (drop.proposedAction == Qt.CopyAction) {
                        console.log(textdata)
                        drop.acceptProposedAction()
                    }
                }
            }
        }
    
        Window {
            id: side_window
    
            title: "drag from window"
            visible: true
    
            width: 400
            height: 400
    
            MouseArea {
                id: mousearea
    
                hoverEnabled: true
    
                width: parent.width
                height: parent.height
            }
    
            DragIcon {
                visible: mousearea.containsMouse
    
                dropdata: ({
                    "display": "some data"
                })
                dragtext: "✋"
                dragkeys: ["displaykey"]
                dragmime: {"amet/displaykey":dropdata}
            }
        }
    }
    
    

    DragIcon.qml:

    import QtQuick 2.15
    import QtQuick.Controls 2.15
    
    Rectangle {
        id: grab_handle
    
        width: 20
        height: 20
    
        property int dragwidth: 20
        property int dragheight: 20
    
        property string dragtext
        property string draggedtext: dragtext
        property var dragkeys: []
        property var dragmime: ({})
        property var dropdata: ({})
        property var dragparent
    
        color: "transparent"
        border.color: "steelblue"
        border.width: 1
    
        Text {
            id: drag_text
    
            anchors.centerIn: parent
    
            text: grab_handle.dragtext
        }
    
        MouseArea {
            id: drag_mousearea
    
            anchors.fill: parent
    
            drag.target: draggable
    
            onReleased: {
                draggable.Drag.drop()
            }
    
            onPressed: draggable.grabToImage(function(result) {
                draggable.Drag.imageSource = result.url
            })
    
            Rectangle {
                id: draggable
    
                objectName: "draggable"
    
                visible: drag_mousearea.drag.active
    
                width: grab_handle.dragwidth
                height: grab_handle.dragheight
                color: "transparent"
    
                border.color: grab_handle.border.color
                border.width: 1
    
                property var dropdata: grab_handle.dropdata
    
                Drag.active: drag_mousearea.drag.active
                Drag.hotSpot.x: 0
                Drag.hotSpot.y: 0
                Drag.keys: grab_handle.dragkeys
                Drag.dragType: Drag.Automatic
                Drag.supportedActions: Qt.CopyAction
                Drag.mimeData: dragmime
    
                Drag.onDragFinished: {
                    Qt.callLater(fixpos, x,y) // fixes drag glitches
                }
                function fixpos(x, y){
                    draggable.x = x
                    draggable.y =y
                }
    
                //states: State {
                    //when: drag_mousearea.drag.active
                    //ParentChange { target: draggable; parent: grab_handle.dragparent }
                    //AnchorChanges { target: draggable; anchors.verticalCenter: undefined; anchors.horizontalCenter: undefined }
                //}
    
                Text {
                    id: dragged_text
    
                    anchors.centerIn: parent
    
                    text: grab_handle.draggedtext
                }
            }
        }
    }
    

    I think it has something to do with the mousearea active, but I just don't see why there is a loop.

    The error occurs once when starting the drag:

    qrc:/DragIcon.qml:47:9: QML Rectangle (parent or ancestor of QQuickDragAttached): Binding loop detected for property "active"
    

    If I don't use mousearea.containsMouse in main.qml to determine visibility it doesn't show this binding loop. Which makes no sense to me.
    Everything works as expected so I have been ignoring this. I don't want this to bite me later.

    Qt 5.15.2 64 bit
    Linux



  • I found where I learned how to bind mousearea.drag.active to Drag.active. So that part "should" be good. I upgraded from 5.15.1. to 5.15.2 to see if this is a library issue. Not that I can tell.

    I just checked and I get the binding loop detection in 5.12.10. So it was not introduced with 5.15.

    Are binding loop detections really sensitive? I put an on changed routine on the Drag.active and it only changes once:

    Drag.onActiveChanged: console.log("Drag.active:", Drag.active)
    


  • Okay, I found how to make it go away. I am not sure if this is a good solution, but it seems to get rid of the binding loop message and does not seem to affect functionality.

    Change this:

    Drag.active: drag_mousearea.drag.active
    

    To this:

    // prevents binding loop with unknown cause
    Binding on Drag.active {
      value: drag_mousearea.drag.active
      delayed: true
    }
    

Log in to reply