Как скрыть окно QML, когда оно теряет фокус

Я пытаюсь создать поле со списком с множественным выбором с помощью QML. Его раскрывающимся списком будет Окно QML с флагом Qt.Popup, поэтому он не будет иметь строку заголовка. Выпадающее меню должно исчезнуть, когда пользователь нажимает на него.

Я попробовал следующий код:

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;
                }
            }
        }
    }
}

И это не работает.

В приведенном выше коде, когда пользователь нажимает на главное окно, появляется всплывающее окно, и если пользователь нажимает на другое окно или на строке заголовка главного окна, он должен исчезать, но он этого не делает.

Если я импортирую версию 2.1 QtQuick.Window вместо 2.0, я могу поместить обработчик onActiveChanged (без получения ошибки) внутри выпадающего окна, но он никогда не вызывается.

Возможно, я смогу сделать это с помощью некоторого С++, но я стараюсь этого избежать.

Я использую Qt 5.1.1 на Ubuntu 13.10.

Спасибо.

Обновление: я переключился на Qt 5.2 и решил проблему (см. мой ответ ниже).

Ответ 1

Сегодня я обновился до Qt 5.2. В Qt 5.2 следующий код работает так, как я хочу:

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;
            }
        }
    }
}

Это работает, потому что в Qt 5.2 QtQuick.Window 2.1 указан в документации в качестве последней версии этого модуля, и он дает мне доступ to QWindow activeChanged сигнал и requestActivate slot (QML Window является эквивалентом QQuickWindow в С++, который является подклассом QWindow).

Ответ 2

Возможно, если вы измените (в обработчике onClicked)

dropdown.visible = true;

в

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

вы получите необходимый результат.

Вот хороший пример DropDown: раскрывающегося списка Qt QML, как в HTML, без использования другого Window.

Ответ 3

Потерянные часы, пытающиеся привязываться к ActiveChanged. Нашел другое решение

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