Dialog and DropArea issue



  • Hi,

    I have a problem with DropArea and Dialog in my QML application using QtQuick.Controls 2 with Qt 5.10 on a Windows 10 system.
    In my application I have a Window with some custom controls (e.g. TableView) having a DropArea that accepts, for example, the drop of files from the file system.
    I have also a modal Dialog (spawning above the main Window) that has Items without their own DropAreas (e.g. Label).

    When I drag a file from Explorer, I notice that the drag event passes through both the modal dialog and the external overlay.
    The event is forwarded to the below Window DropArea (the onEntered callback is called on it).
    If I drop the file on the Dialog or on the modal overlay, the drop event is captured by the Window DropArea too!

    I simply would like to avoid this propagation when the dialog is shown.

    I tried to fix the Dialog by adding a DropArea filling it that accepts the drag event in the onEntered callback but, if I do that,
    I notice that the cursor shape is changing to "+ Copy" when I try to drag on the dialog DropArea (that is wrong since I want refuse the drop).
    Otherwise if I don't accept the event by writing "drag.accepted = false", the DropEvent goes back to be handled by the Window's DropArea (wrong again).

    In addition I would rather the DragEvent not to pass through the modal dialog external overlay.

    Here is a sample code:

    import QtQuick 2.8
    import QtQuick.Window 2.3
    import QtQuick.Controls 2.2
    
    ApplicationWindow {
        id: root
    
        visible: true
        width: 640
        height: 480
    
        Rectangle {
            anchors.fill: parent
            color: windowDropArea.containsDrag ? "red" : "blue"
    
            DropArea {
                id: windowDropArea
                anchors.fill: parent
                onEntered: {
                    console.log("windowDropArea onEntered")
                    drag.accept()
                }
                onDropped: {
                    console.log("windowDropArea onDropped")
                }
            }
        }
    
        Button {
            anchors.centerIn: parent
            text: "Open dialog"
            onClicked: dialog.open()
        }
    
        Dialog {
            id: dialog
    
            width: parent.width / 2
            height: parent.height / 2
            x: 0 // spawn on top-left
            y: 0
            modal: true
            dim: true
            closePolicy: Popup.CloseOnPressOutside
            padding: 0
    
            contentItem: Item {
    
    
                Rectangle {
                    anchors.fill: parent
                    color: dialogDropArea.containsDrag ? "green" : "yellow"
                }
    
                DropArea {
                    id: dialogDropArea
                    anchors.fill: parent
                    onEntered: {
                        console.log("dialogDropArea onEntered")
                        drag.accept() // if not accept (drag.accepted = false), event is pass to the window DropArea below
                        // drag.accept(Qt.IgnoreAction) // also tried this, nothing change
                    }
                    onDropped: {
                        console.log("dialogDropArea onDropped")
                    }
                }
            }
        }
    }
    

    Try to open the dialog and drag a file from Explorer, both by entering the dialog from the top-left corner and from elsewhere.



  • Update:
    Drag on the overlay issue may be solved by adding a custom Item as overlay.modal having a DropArea.
    By te way, as shown in the sample, I think the right solution should be accept the event by

    drag.accept(Qt.IgnoreAction)
    

    but the cursor shape still change to "+ Copy" when I try to drag on the dialog DropArea.



  • @Rulez said in Dialog and DropArea issue:

    Update:
    Drag on the overlay issue may be solved by adding a custom Item as overlay.modal having a DropArea.
    By te way, as shown in the sample, I think the right solution should be accept the event by

    drag.accept(Qt.IgnoreAction)
    

    but the cursor shape still change to "+ Copy" when I try to drag on the dialog DropArea.

    Update: nope, this does not work!
    Overlay mouse area capture the event when entering on its DropArea (onEnter callback) and, since the drop position never exits from the Overlay, the internal (overlapped) dialog DropArea is not activated (onEnter is not called!)

    Am I doing something wrong? These areas seem to have too many problems!
    Please help!



  • In conclusion:

    • nested DropAreas must be in the same hierarchy to detect entering of the drag event on the internal DropArea (such as for MouseAreas)
    • QtQuick.Controls 2 Dialog does not block drag event when is not accepted by any Item of the Dialog, therefore drag event passes through it leading to the potential DropAreas of the below Window (wrong in my opinion)
    • QtQuick.Controls Dialog (instead) is similar to a Window and blocks the drag event when is not accepted by any Item of the Dialog
    • Window Modal Overlay does not lock drag event (wrong: bug https://bugreports.qt.io/browse/QTBUG-56236 ) and the workaround which consists of add a custom overlay with a DragArea does not work since the DropArea is sibling of Window items (see first point)

    So, a possible workaround at the moment may be rollback to QtQuick.Controls Dialog trying to manage the presence of the overlay DropArea (that accept drop event) manually.
    By the way cursor shape continues to be wrong when I accept the drag event (also with Qt.IgnoreAction) with the intention to refuse the drop.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.