简体   繁体   English

如何在失去焦点时隐藏QML窗口

[英]How to hide a QML Window when it loses focus

I am trying to create a combo box with multiple selection using QML. 我正在尝试使用QML创建一个包含多个选择的组合框。 Its dropdown will be a QML Window with the flag Qt.Popup so it will not have a title bar. 它的下拉列表将是一个带有Qt.Popup标志的QML窗口,因此它没有标题栏。 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. 如果我导入QtQuick.Window的2.1版本而不是2.0,我可以在下拉窗口中放置一个'onActiveChanged'处理程序(不会出现错误),但它永远不会被调用。

Maybe I would be able to do this using some C++ but I try to avoid that. 也许我可以使用一些C ++来做到这一点,但我尽量避免这种情况。

I use Qt 5.1.1 on Ubuntu 13.10. 我在Ubuntu 13.10上使用Qt 5.1.1。

Thank you. 谢谢。

Update: I switched to Qt 5.2 and solved the problem (see my answer below). 更新:我切换到Qt 5.2并解决了问题(请参阅下面的答案)。

Today I upgraded to Qt 5.2. 今天我升级到Qt 5.2。 In Qt 5.2 the following code works as I want: 在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;
            }
        }
    }
}

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 ). 它的工作原理是,在Qt 5.2中, QtQuick.Window 2.1 在文档中被指定为该模块的最新版本,它使我能够访问QWindowactiveChanged信号requestActivateQML Window相当于C ++中的QQuickWindow ,是QWindow的子类)。

Probably, if you change (in onClicked handler) 可能,如果你改变(在onClicked处理程序中)

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 . 有一个很好的DropDown示例: Qt QML下拉列表,就像在HTML中一样,没有使用另一个Window

Lost hours trying to bind to ActiveChanged. 试图绑定到ActiveChanged的小时数。 Found another solution 找到另一个解决方

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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