我遇到一个问题,即用户可以通过top_level
方法打开等待变量的wait_variable()
窗口。但是当top_level
窗口打开时,root
窗口仍然可见,用户可以通过常规方法关闭root
窗口(这是故意的)。我想要的是(并期望tkinter做),在.destroy()
窗口调用.quit()
或root
将导致所有root
个孩子成为终止。但似乎正在发生的事情是top_level
窗口仍然停留在其本地事件循环中,并且只有在其父级已经消失后才能通过任务管理器终止。
那么我做错了什么?如何让top_level
窗口在本地事件循环中监听它的父母被破坏?
下面是一些演示此问题的示例代码。如果您运行代码并按照以下步骤操作,IDE将崩溃!可能,所以除了工作。按下root中的Click
按钮。顶级窗口将显示另一个显示Test
的按钮。现在关闭root
窗口。 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()
编辑:我当前的解决方案是在WM_DELETE_WINDOW
窗口启动时重新指定top_level
协议,设置为设置本地事件循环等待的变量的函数,然后销毁root
窗口。
答案 0 :(得分:2)
正确的解决方案IMO是不等待变量,而是等待窗口。然后,您的按钮必须承担销毁窗口的责任,而不是设置变量。
这是另一个原因的正确解决方案:如果用户使用标题栏中的按钮销毁顶层,则程序也会挂起。由于您正在等待变量,因为窗口被破坏,变量将永远不会被设置。
(您在编辑中提出的解决方案也是有效的 - 在窗口中注册WM_DELETE_WINDOW以在窗口被销毁时设置变量。效果将是相同的。)