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时设置变量。效果是一样的)。
我有一个问题,用户可以打开 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时设置变量。效果是一样的)。