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

时间:2021-05-12 22:17:59

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.

我正在尝试使用QML创建一个包含多个选择的组合框。它的下拉将是一个带有标志Qt.Popup的QML窗口,因此它将没有标题栏。当用户单击下拉菜单时,下拉菜单应该会消失。

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的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解决了这个问题(见下面我的答案)。

3 个解决方案

#1


8  

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

今天我升级到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;
            }
        }
    }
}

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。在文档中,窗口2.1被指定为该模块的最新版本,它允许我访问QWindow的activeChanged信号和requestActivate插槽(QML窗口相当于c++中的QQuickWindow,它是QWindow的一个子类)。

#2


3  

Probably, if you change (in onClicked handler)

如果您更改(在onclick处理程序中)

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.

有一个很好的下拉的例子:Qt QML下拉列表,就像在HTML中那样,不使用另一个窗口。

#3


0  

Lost hours trying to bind to ActiveChanged. Found another solution

失去的时间试图与行动结合改变。发现另一个解决方案

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

#1


8  

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

今天我升级到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;
            }
        }
    }
}

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。在文档中,窗口2.1被指定为该模块的最新版本,它允许我访问QWindow的activeChanged信号和requestActivate插槽(QML窗口相当于c++中的QQuickWindow,它是QWindow的一个子类)。

#2


3  

Probably, if you change (in onClicked handler)

如果您更改(在onclick处理程序中)

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.

有一个很好的下拉的例子:Qt QML下拉列表,就像在HTML中那样,不使用另一个窗口。

#3


0  

Lost hours trying to bind to ActiveChanged. Found another solution

失去的时间试图与行动结合改变。发现另一个解决方案

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