34

I have a master Frame (call it a), and a popup Toplevel (call it b). How do I make sure the user cannot click on anything in a while b is "alive"?

Daniel Kats
  • 5,141
  • 15
  • 65
  • 102

1 Answers1

58

If you don't want to hide the root but just make sure the user can only interact with the popup, you can use grab_set() and grab_release().

Example app, tested with Python 3.7 and 3.8:

import tkinter as tk
import sys
import platform


class Popup:
    def __init__(self):
        self.tl = None
        self.root = tk.Tk()
        self.root.title("Grab Set/Release")

        tk.Label(self.root, text=f"Python v{platform.python_version()}").pack(padx=12, pady=12)
        tk.Button(self.root, text="Popup!", width=20, command=self.popup).pack(padx=12, pady=12)
        tk.Button(self.root, text="Exit", width=20, command=sys.exit).pack(padx=12, pady=12)

        self.root.mainloop()

    def popup(self):
        if self.tl is None:
            self.tl = tk.Toplevel()
            tk.Button(self.tl, text="Grab set", width=20, command=self.lock).pack(padx=12, pady=12)
            tk.Button(self.tl, text="Grab release", width=20, command=self.unlock).pack(padx=12, pady=12)

    def lock(self):
        self.tl.grab_set()
        print("Grab set!")

    def unlock(self):
        self.tl.grab_release()
        print("Grab released!")


Popup()

Alternatively, you could withdraw() the root to make it invisible:

root.withdraw()

will leave the root alive, but only b visible.

If you need it back, you can do

root.deiconify()
Junuxx
  • 14,011
  • 5
  • 41
  • 71
  • 3
    Just to add to your answer, I found the documentation on this (after a bit of digging) here: http://effbot.org/tkinterbook/tkinter-dialog-windows.htm – Daniel Kats Mar 12 '13 at 14:56
  • 4
    In most cases, `grab_release()` isn't necessary. If `grab_set()` is used on a window, control is automatically released when the window is closed. – Stevoisiak Feb 22 '18 at 19:05
  • Is it possible to gray out the background window? (Without graying our each component individually) – Nagabhushan S N May 30 '20 at 05:08
  • 4
    Is first one (`grab_set()`) still working on latest tkinter and Python 3.7.9? These functions doesn't effects. – Yılmaz Alpaslan Jun 09 '21 at 07:18
  • @YılmazAlpaslan: Yes it should still work in Python 3.7 and up. Expanded the example with working code. If you run it, you will find that you can't interact with the root window when "grab_set" is called from the popup window. – Junuxx Jul 14 '23 at 00:13