Kivy - 检查当前是不是显示弹出窗口(因为 Kivy 弹出窗口不是真正的模态(后退按钮/键盘))

Posted

技术标签:

【中文标题】Kivy - 检查当前是不是显示弹出窗口(因为 Kivy 弹出窗口不是真正的模态(后退按钮/键盘))【英文标题】:Kivy - check if popup is currently showing (because Kivy Popup isn't really modal (back button/keyboard))Kivy - 检查当前是否显示弹出窗口(因为 Kivy 弹出窗口不是真正的模态(后退按钮/键盘)) 【发布时间】:2016-06-04 18:08:01 【问题描述】:

我在我的根小部件中绑定到 Window.on_key_down 以处理 android 的后退按钮。

ModalView(它是子 Popup)并不是真正的模态视图,它们根本不处理键盘,因此也不处理后退按钮。

如果我从 Popup 继承并绑定到返回 True 的 Window.on_key_down,那么我可以从我的继承类中处理后退按钮。此时我可以在 on_dismiss 中取消绑定或删除小部件(似乎无法让删除可靠地工作,但这不是一个单独的问题)。

问题在于,这将我对所有屏幕(我使用屏幕管理器)而不是在我的根小部件中对后退按钮的处理划分出来。因此,我正在寻找一种方法来从我的根小部件检查当前是否打开了任何弹出窗口(最好不要遍历小部件树,因为不会很好地扩展)。请就我在下面考虑的选项以及任何其他建议提出建议:-

选项 1

在根小部件中初始化的单个弹出小部件,所有屏幕将在必要时修改/open()。当然,这将需要绑定/取消绑定该弹出窗口的按钮。然后,根小部件可以轻松检查该单个对象以查看其是否打开。

选项 2

在从弹出窗口小部件继承的类中处理键盘,并在最后取消绑定键盘。将返回按钮处理拆分为多个文件/屏幕的问题,以及在长期使用该应用程序时构建旧的弹出窗口小部件的问题。

选项 3

???

【问题讨论】:

您是否考虑过维护某种根应用程序级别的属性,它代表所有打开的弹出窗口的列表? 我有(之前做过类似的事情来跟踪有或没有焦点的文本输入),但我看不出这种方法比选项 1 有任何优势,因为它仍然会紧密耦合子小部件到根目录,同时与单个弹出窗口相比,将代码分发得更远。当然,好处是不需要绑定 【参考方案1】:

假设您正在运行一个 kivy 应用程序 (kivy.app),您可以在后退按钮回调中执行以下操作:

from kivy.app import App
from kivy.uix.popup import Popup

if isinstance(App.get_running_app().root_window.children[0], Popup):
    App.get_running_app().root_window.children[0].dismiss()

弹出窗口将在其open() 方法中将Popup 类型的对象添加到窗口对象(add_widget() 的默认行为,假定插入索引为 0)。

在稍微复杂的情况下(多个弹出窗口或使用 inspector 模块),遍历所有子级也可以。

from kivy.app import App
from kivy.uix.popup import Popup

for widget in App.get_running_app().root_window.children:
    if isinstance(widget, Popup):
        widget.dismiss()

【讨论】:

感谢您的回答,有时间我将不得不对其进行测试。实际上,我想查看 Popup 代码以确保它确实在前面。还要看看多个 ModalView 会发生什么 =) 所以 ModalView 代码确实 add_widget() 到窗口,默认在 index = 0 处添加,所以只要没有其他小部件添加到窗口,您的解决方案就可以正常工作。为此添加注释,并接受您的回答,谢谢! 对不起,这个答案不再有效,因为我的应用程序上的进一步实时测试表明 children[0] 可能并不总是弹出窗口。特别是在运行检查器模块python main.py -m inspector 时,它总是优先。我想我需要遍历孩子列表才能做到这一点。必须查看多个弹出窗口是否总是“最后一个是最低索引”。 如果您在打开弹出窗口后向窗口对象添加另一个小部件,它不会是第一个对象。迭代孩子可能会很好。我希望订单不会改变,但我没有测试过。 inspector 模块是 Kivy 内置的,之后并没有真正添加,我认为它始终是第一个孩子(因为它的作用是有道理的)。遍历孩子确实有效,让我编辑您的答案并重新接受它。

以上是关于Kivy - 检查当前是不是显示弹出窗口(因为 Kivy 弹出窗口不是真正的模态(后退按钮/键盘))的主要内容,如果未能解决你的问题,请参考以下文章

访问 kivy 弹出父级

更改 Kivy 中的弹出文本

在 Kivy 中,如何使用另一个类的关闭按钮关闭弹出窗口?

Kivy:访问不同类的方法

Kivy Python 中的弹出窗口 - 显示在前面

kivy:带有进度条的弹出窗口