Tkinter。如何在顶层 window 等待变量时销毁根 window

Tkinter. How to destroy the root window while top level window is waiting for a variable

我有一个问题,用户可以打开 top_level window,它通过 wait_variable() 方法等待变量。但是当 top_level window 打开时, root window 仍然可见并且用户可以通过通常的方式关闭 root window方法(这是故意的)。我想要的(并且有点期望 tkinter 做的)是在 root window 上调用 .destroy().quit() 将导致所有 root' s children 被终止。但是似乎正在发生的是 top_level window 仍然停留在其本地事件循环中,并且只能在其 parent 消失后通过任务管理器将其杀死。

那我做错了什么?我如何让 top_level window 在本地事件循环中监听它的 parent 破坏?

.

下面是一些演示该问题的示例代码。如果您 运行 代码并按照以下步骤操作,您的 IDE 将会崩溃!!可能,所以节省你的工作。在 root 中按下 Click 按钮。顶层 window 将与另一个显示 Test 的按钮一起出现。现在关闭 root window。 IDE 将挂起。

import tkinter
root = tkinter.Tk()
def toplevel(event=None):
    def set1(event=None):
        vr.set(1)
    tp = tkinter.Toplevel(root)
    vr = tkinter.IntVar()
    bt_ = tkinter.Button(tp,text='Test',command=set1)
    bt_.grid()
    tp.wait_variable(vr)
    tp.destroy()
bt = tkinter.Button(root,text='Click',command=toplevel)
bt.grid()
root.mainloop()

编辑: 我目前的解决方案是在 top_level window 启动时将 WM_DELETE_WINDOW 协议重新指向一个设置本地事件循环正在等待的变量,然后销毁 root window.

IMO 的正确解决方案是 不是 等待变量,而是等待 window。然后,您的按钮必须承担销毁 window 的责任,而不是或除了设置变量之外。

由于另一个原因,这是正确的解决方案:如果用户使用标题栏中的按钮破坏顶层,您的程序也会挂起。因为你在等待一个变量,因为 window 被破坏了,变量将永远不会被设置。

(您在编辑中提出的解决方案也是有效的-在顶层注册WM_DELETE_WINDOW以在销毁window时设置变量。效果是一样的)。