Reputation: 1426
I have an issue whereby a user can open a top_level
window which sits waiting for a variable via the wait_variable()
method. But while the top_level
window is open, the root
window is still visible and the user is able to close the root
window via usual methods (this is intentional). What I'd like (and sort of expect tkinter to do) is that calling .destroy()
or .quit()
on the root
window will cause all of root
's children to be terminated. But what appears to be happening is that the top_level
window remains stuck in its local event loop and can only be killed via the task manager once its parent has gone.
So what am I doing wrong? How do I get the top_level
window to listen out for it's parents destruction while its in a local event loop?
.
Below is some example code that demonstrates the issue. If you run the code and follow the steps below your IDE WILL CRASH!! probably, so save you work. Push the Click
button in root. The top level window will appear with another button that says Test
. Now close the root
window. The IDE will hang.
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()
Edit: My current solution is to repoint the WM_DELETE_WINDOW
protocol when the top_level
window starts, to a function that sets the variable that the local event loop is waiting for, and then destroys the root
window.
Upvotes: 1
Views: 1330
Reputation: 385930
The correct solution IMO is to not wait on the variable, but rather, wait on the window. Your button then must take on the responsibility of destroying the window instead of or in addition to setting the variable.
This is the right solution for another reason: as written your program will also hang if the user destroys the toplevel with the buttons in the titlebar. Since you're waiting on a variable, because the window is destroyed the variable will never be set.
(the solution you proposed in your edit is also valid -- register with WM_DELETE_WINDOW on the toplevel to set the variable when the window is destroyed. The effect will be the same).
Upvotes: 2