How to automatically close a Dialog when clicked outside?



  • Hi,
    Does anybody know how to close a qml Dialog when user clicks outside of it?
    This is a common behavior for Android/iOS apps, but I couldn't figure out how to do it with QML Dialog component.
    Thank you,
    Bruno



  • Good question. I also want to know the answer to this question
    May be using focusChanged can help?


  • Qt Champions 2016

    One of the solution is InverseMouseArea from Ubuntu SDK. It capture the mouse event outside of your component. However, Qt did not bundle this component. You may find the C++ implementation from Ubuntu or got a QML version from this page:

    https://github.com/benlau/quickandroid/blob/master/QuickAndroid/InverseMouseArea.qml

    (Remember to destroy the component after closed the dialog.)



  • @tezine You could use a QtQuick Window with the Window.Popup flag set. Unfortunately this feature is buggy in the current Qt version. I faced the same problem and was able to work around it. See this thread: http://forum.qt.io/topic/51393/window-with-qt-popup-not-closed/2
    Cheers!



  • @benlau I thought that a dialog/window didn't get mouse events outside the dialog from the protected event() function making the inverse mouse area only work inside of the screen? The reason I say this is because I thought those events were passed to Qt from the windowing system. Which I don't think would tell you the mouse position if you didn't set some special flag or were the window that actually contained the mouse.


  • Qt Champions 2016

    @Buttink I assume tezine means iOS and Android platform. I think the implementation of Dialog class in those platform do not create a new window. It is still a QQuickItem. So the hijacking by MouseArea works.

    But there has two problems. The first , Dialog is not a QQuickItem. And the QML version of InverseMouseArea do not working well in this situation.

    It could be fixed by this experimental InverseMouseArea:
    https://gist.github.com/benlau/a0d57b865fe9eaf03c10

    And hijack the dialog by

      FileDialog {
        id: fileDialog
     }
    
    InverseMouseArea {
        id: inverseMouseArea
        width: parent.width
        height: parent.height
        enabled: fileDialog.visible
        parent : fileDialog.contentItem
    
        onPressed: {
            fileDialog.close();
        }


  • Hi all,
    @benlau it worked with your experimental InverseMouseArea.
    I had to comment the line parent: fileDialog.contentItem and the dialog must have: modality: Qt.NonModal
    Besides that, it worked perfectly!
    Thank you,
    Bruno.



  • Hi @benlau , I forgot to mention, I commented the line inside InverseMouseArea: //if (!_inBound(pt)). Just sends component.pressed();
    Here is an example of use:
    Dialog {
    id: sharedDlg
    modality: Qt.NonModal
    property alias inverseParent: inverseMouseArea.parent
    InverseMouseArea {
    id: inverseMouseArea
    width: 400
    height: 600
    enabled: sharedDlg.visible
    onPressed: sharedDlg.close()
    }
    }

    //extending Dialog with InverseMouseArea....
    MyDialog {
    id: dlg
    contentItem: Rectangle {
    implicitWidth:400
    implicitHeight:600
    //add content here
    }
    }

    //using MyDialog....
    MyDialog{
    inverseParent: topWindow
    }



  • My solution for automatically close a Dialog in qml by clicking outside the window was to change the modality of the window to non modal:

    Dialog
        {
            id: myDialog
            height: 300
            width: 600
            modality: Qt.NonModal
    ...
    

    My window has a 1280x800 size and the dialog appears in the middle. Once its open i click outside and the Dialog closes by itself.



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