Search code examples
pythontkinterwindowtk-toolkit

Efficient way to create a child window with access to main window disabled?


I'm looking for the most efficient way to create a child window and also forbid all access to the main window, in order that user will have to click on "OK" button inside the child window in order to recover the access to the main window.

Here is my code, using Toplevel class. It works, but is there a more efficient way to do ?

from tkinter import *

class MainWindow(Tk):

    def __init__(self):
        Tk.__init__(self)

    def SetEnableStatus(self, status):
        for w in self.winfo_children():
            if status == False:
                w.grab_set()
            else:
                w.grab_release()

    def CreateChildWindow(self):            
        subWindow = Toplevel(self)

        def quit_subwindow():
            subWindow.destroy()
            self.SetEnableStatus(True) # Enable all widgets of main window

        Button(subWindow, text='Exit', command=quit_subwindow).pack()

        self.SetEnableStatus(False) # Disable all widgets of main window

Solution

  • It should be enough to call grab_set on the Toplevel object, and when you are done with it, you can simply destroy it, and call grab_set on self (but I am not 100% sure, even if the resulting program below confirms it).

    In fact, if you create a button on your Tk root window and if you associate with this button for example a lambda function that prints something, then nothing will be printed, after "setting the grab" on the child window.

    See the following example where basically all events are redirected to the Toplevel window, instead of to the Tk root window:

    from tkinter import *
    
    
    class MainWindow(Tk):
    
        def __init__(self):
            Tk.__init__(self)
            Entry(self).pack(side="left")
            Button(self, text="whoami", command=lambda : print("A Tk root window.")).pack(side="left")
    
        def CreateChildWindow(self):            
            subWindow = Toplevel(self)
    
            def quit_subwindow():
                subWindow.destroy()
                self.grab_set()
    
            Button(subWindow, text="whoami", command=lambda : print("A Toplevel child window.")).pack()
            Button(subWindow, text='Exit', command=quit_subwindow).pack()
            subWindow.grab_set()
    
    
    win = MainWindow()
    win.CreateChildWindow()
    win.mainloop()
    

    Check out the following article at effbot.org to know more about how to create dialogs:

    http://effbot.org/tkinterbook/tkinter-dialog-windows.htm