Blocking Input Dialog Box Blocking Input Dialog Box tkinter tkinter

Blocking Input Dialog Box


The solution requires two critical pieces. First, use grab_set to block all events in the other window (or, more correctly, send all events to the dialog window). Second, use wait_window to prevent the method from returning until the dialog has been destroyed.

That being said, you shouldn't be using it like in your example. You need to have the mainloop running before you create the window. It might work OK on some platforms, but in general you shouldn't expect your GUI to behave properly until mainloop is running.

Here's a simple example:

import Tkinter as tkclass MyDialog(object):    def __init__(self, parent, prompt):        self.toplevel = tk.Toplevel(parent)        self.var = tk.StringVar()        label = tk.Label(self.toplevel, text=prompt)        entry = tk.Entry(self.toplevel, width=40, textvariable=self.var)        button = tk.Button(self.toplevel, text="OK", command=self.toplevel.destroy)        label.pack(side="top", fill="x")        entry.pack(side="top", fill="x")        button.pack(side="bottom", anchor="e", padx=4, pady=4)    def show(self):        self.toplevel.grab_set()        self.toplevel.wait_window()        value = self.var.get()        return valueclass Example(tk.Frame):    def __init__(self, parent):        tk.Frame.__init__(self, parent)        self.button = tk.Button(self, text="Click me!", command=self.on_click)        self.label = tk.Label(self, text="", width=40)        self.label.pack(side="top", fill="x")        self.button.pack(padx=20, pady=20)    def on_click(self):        result = MyDialog(self, "Enter your name:").show()        self.label.configure(text="your result: '%s'" % result)if __name__ == "__main__":    root = tk.Tk()    Example(root).pack(fill="both", expand=True)    root.mainloop()