“wait_window”方法是做什么的?

18

调用此方法的对象似乎在等待作为参数传递的窗口被销毁后才继续自己的循环...

Misc类的文档字符串中,我们可以观察到:

def wait_window(self, window=None):
    """Wait until a WIDGET is destroyed.
    If no parameter is given self is used."""
乍一看,似乎这种方法可以使一个Toplevel模态化,但事实并非如此。要使Toplevel模态化,我们必须使用grab_set()方法。 我看过其他解释:
  < p > wait_window 似乎不会返回,直到传递的小部件作为参数未被销毁。

从另一个地方来:
   

wait_window(widget) - 创建一个本地事件,等待给定的小部件被销毁。这个循环不影响应用程序的主循环。

effbot 文档中,我们看到:
  

wait_window 进入本地事件循环,并在给定窗口被销毁(通过destroy方法或显式关闭窗口管理器)之前不返回:

widget.wait_window(window)

一个 window 等待另一个 window(它自己)是什么意思?

似乎在调用 wait_window 后的代码直到传递给同一方法的窗口被销毁之前都不会执行。 在下面的工作示例中,我们可以看到对刚才说的内容的证明:

from tkinter import *

def on_win_request(parent):
    dialog = Toplevel()
    parent.wait_window(dialog)
    # executed only when "dialog" is destroyed
    print("Mini-event loop finished!")

r = Tk()
b = Button(r, text='New Window', command=lambda: on_win_request(r))
b.pack()
b2 = Button(r, text='Hello!', command=lambda: print("hello"))
b2.pack()
r.mainloop()

只有当本地 Toplevel 小部件被销毁时,才会打印出 "Mini-event loop finished!"

那么,在什么实际情况下我应该使用这种方法?


我似乎在构造函数中阻塞了应用程序,直到对话窗口被销毁。您不希望等待父级,因为您只想在用户与对话框交互时阻止。由于我已经很久没有做过GUI编程了,也不确定主线程如何处理GUI事件,所以我还没有给出一个恰当的答案。 - Jmac
@Jmac 根据 effbot 上的说明,wait_window 进入一个本地事件循环,并且在给定的窗口参数被销毁之前不会返回。因此,在我们对父窗口调用 wait_window 的情况下,我们将进入一个本地循环(我猜是在对话框中,或者也许不是?),并且在对话框被销毁之前不会将控制权返回给父窗口... - nbro
@Jmac 然后还有另一个例子,其中root正在等待Toplevelroot.wait_window(d.top),这就是为什么基本上是父组件让子组件在本地循环上运行,直到子组件被销毁。 - nbro
我的上一个评论有点不准确:请忽略它。重新阅读后,wait_window 似乎会阻塞,直到在给定的窗口中发生事件,并且将在给定的窗口中发生销毁窗口事件时返回。在这种情况下,调用子窗口的 wait_window 正好与调用父窗口的相同。 - Jmac
对我来说,使用self.wait_window比使用self.parent.wait_window更加清晰。这是_child_的init方法等待子类中发生的事件,而不是父类等待事件。如果您创建了父类,则可以让父窗口调用其wait_window方法以等待子类。但在这个简单的例子中,父类是根窗口,因此从子类调用wait_window是最合理的选择。 - Jmac
显示剩余2条评论
1个回答

23

像文档所述,它会等待给定的窗口被销毁。它主要用于模态弹出窗口,但它本身并不使窗口成为模态。函数调用简单地等待目标窗口被销毁,要使一个窗口成为模态窗口,你还需要执行抓取操作。

最常见的用法是创建Toplevel实例,填充该窗口小部件,然后等待窗口被关闭再执行其他操作。在等待期间,tkinter仍然能够正常处理事件。

例如,你可以禁用(或延迟创建)主GUI,弹出“条款和条件”通知,并等待用户确认服务条款、版权、许可等。一旦窗口被销毁,你就可以完成初始化,或者启用一些小部件等。

标准文件对话框就是一个完美的例子:你弹出对话框,然后代码等待用户选择文件,然后使用返回的文件名。在内部,对话框的实现使用wait_window,以便它在对话框被关闭之前不会返回。


1
我理解了,但在什么实际情况下它会有用呢?你能给我举些例子吗? - nbro
@rinzler:文件对话框是一个例子:要求用户选择一个文件,然后加载该文件。警告窗口是另一个例子。在缺乏本地对话框的平台上,对话框被实现为顶级窗口,并使用wait_window等待用户单击按钮、选择文件、选择字体等。 - Bryan Oakley
1
但在一些示例中,我们有window.wait_window(window),这对于一个窗口等待自己意味着什么?与root.wait_window(window)相比有什么区别? - nbro
我曾经在某个地方读到过,wait_window 之所以是一个方法而不是全局函数的唯一原因是为了减少命名空间污染,所以我想没有什么区别... - nbro
1
@Rinzler:想一想文件对话框的内部工作原理:它等待自己。你不必在应用程序中添加代码来等待对话框被销毁,因为对话框会为你完成这个任务。 - Bryan Oakley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接