Search code examples
pythonooptkintermainloop

Continue executing function


When closing an instance of the ChildWindow class, which was called from another instance of MainWindow, the code does not continue to be executed.

I noticed that only when the MainWindow instance is closed does it continue to run. In general, it has a cumulative property, so the number of times the ChildWindow closes the window, the continuation will be displayed.

I want the function to continue executing when the ChildWindow closes, without closing the main window. Here's my code:

from tkinter import *

class MainWindow():

    def __init__(self):
        self.root = Tk()
        
    def run(self):
        Button(self.root, text='click', command=lambda:self.open_child_window()).pack()
        self.root.mainloop()

    def open_child_window(self):
        A = ChildWindow()
        A.run()
        print("why i'm not write?")

class ChildWindow():

    def __init__(self):
        self.root = Toplevel()

    def run(self):
        self.root.mainloop()


A = MainWindow()
A.run()

It seems to me that this is due to the self.root.mainloop() loop, so I was looking for how to stop it, the .quit(), .destroy() methods do not help.


Solution

  • It's called a nested event loop or modal loop. Use the mainloop() and quit() like this.

    class ChildWindow():
        def __init__(self):
            self.root = Toplevel()
    
        def run(self):
            win = self.root
            def on_close():
                win.destroy()
                win.quit()
            win.protocol('WM_DELETE_WINDOW', on_close)
            win.mainloop()
            print('end of the nested loop')
    ...
    

    You can also use wait_window() and destroy() like this.(The former runs a nested event loop until the window is destroyed.)

    class ChildWindow():
        ...
        def run(self):
            win = self.root
            def on_close():
                win.destroy()
            win.protocol('WM_DELETE_WINDOW', on_close)
            win.wait_window()