简体   繁体   中英

How to hide a QML Window when it loses focus

I am trying to create a combo box with multiple selection using QML. Its dropdown will be a QML Window with the flag Qt.Popup so it will not have a title bar. The dropdown should disappear when the user clicks outside of it.

I tried the following code:

import QtQuick 2.0
import QtQuick.Window 2.0

Window { id: mainWindow
    width: 200
    height: 200
    MouseArea {
        anchors.fill: parent
        onClicked: {
            dropdown.x = mainWindow.x + 50;
            dropdown.y = mainWindow.y + 50;
            dropdown.visible = true;
        }
    }

    Window { id: dropdown
        height: 200
        width: 200
        flags: Qt.Popup
        color: 'green'
        visible: false
        onVisibleChanged: {
            if (visible) {
                focusScope.focus = true;
                focusScope.forceActiveFocus();
            }
        }

        FocusScope { id: focusScope
            focus: true
            anchors {
                fill: parent
            }

            onActiveFocusChanged: {
                if (!activeFocus) {
                    dropdown.visible = false;
                }
            }
        }
    }
}

And it doesn't work.

In the code above when the user clicks on the main window, a popup appears and if the user clicks on another window or on the title bar of the main window it should disappear but it doesn't do that.

If I import version 2.1 of QtQuick.Window instead of 2.0 I can put a 'onActiveChanged' handler (without getting an error) inside the dropdown Window but it is never called.

Maybe I would be able to do this using some C++ but I try to avoid that.

I use Qt 5.1.1 on Ubuntu 13.10.

Thank you.

Update: I switched to Qt 5.2 and solved the problem (see my answer below).

Today I upgraded to Qt 5.2. In Qt 5.2 the following code works as I want:

import QtQuick 2.2
import QtQuick.Window 2.1

Window { id: mainWindow
    width: 200
    height: 200
    MouseArea {
        anchors.fill: parent
        onClicked: {
            dropdown.x = mainWindow.x + 50;
            dropdown.y = mainWindow.y + 50;
            dropdown.visible = true;
            dropdown.requestActivate();
        }
    }

    Window { id: dropdown
        height: 200
        width: 200
        flags: Qt.Popup
        color: 'green'
        visible: false
        onActiveChanged: {
            if (!active) {
                dropdown.visible = false;
            }
        }
    }
}

It works because, in Qt 5.2, QtQuick.Window 2.1 is specified in the documentation as the latest version of that module and it gives me access to QWindow 's activeChanged signal and requestActivate slot ( QML Window is the equivalent of QQuickWindow in C++, which is a subclass of QWindow ).

Probably, if you change (in onClicked handler)

dropdown.visible = true;

to:

dropdown.flags = Qt.Window
dropdown.visible = true;
dropdown.flags = Qt.Popup

you will get necessary result.

There is a nice example of DropDown : Qt QML dropdown list like in HTML without using another Window .

Lost hours trying to bind to ActiveChanged. Found another solution

onActiveFocusItemChanged: {
    if (!activeFocusItem) {
        _.visible = false
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM