Tkinter Toplevel : Destroy window when not focused Tkinter Toplevel : Destroy window when not focused tkinter tkinter

Tkinter Toplevel : Destroy window when not focused


You can try something like that :fen is your toplevel

fen.bind("<FocusOut>", fen.quit)


I had a similar problem, and fixed it. The following example works fine.It displays a Toplevel window on top of the main window, as a customized config menu.Whenever the user clicks somewhere else, the config menu disappears.

Warning: Don't use .transient(parent) on the Toplevel window, otherwise, the symptom that you described happens: when clicking on the main window, the menu does not disappear. You can try in the example below to uncomment the "self.transient(parent)" line to reproduce your issue.

Example:

import Tixclass MainWindow(Tix.Toplevel):    def __init__(self, parent):        # Init        self.parent = parent        Tix.Toplevel.__init__(self, parent)        self.protocol("WM_DELETE_WINDOW", self.destroy)        w = Tix.Button(self, text="Config menu", command=self.openMenu)        w.pack()    def openMenu(self):        configWindow = ConfigWindow(self)        configWindow.focus_set()class ConfigWindow(Tix.Toplevel):    def __init__(self, parent):        # Init        self.parent = parent        Tix.Toplevel.__init__(self, parent)        # If you uncomment this line it reproduces the issue you described        #self.transient(parent)        # Hides the window while it is being configured        self.withdraw()        # Position the menu under the mouse        x = self.parent.winfo_pointerx()        y = self.parent.winfo_pointery()        self.geometry("+%d+%d" % (x, y))        # Configure the window without borders        self.update_idletasks() # Mandatory for .overrideredirect() method        self.overrideredirect(True)        # Binding to close the menu if user does something else        self.bind("<FocusOut>", self.close)  # User focus on another window        self.bind("<Escape>", self.close)    # User press Escape        self.protocol("WM_DELETE_WINDOW", self.close)        # The configuration items        w = Tix.Checkbutton(self, text="Config item")        w.pack()        # Show the window        self.deiconify()    def close(self, event=None):        self.parent.focus_set()        self.destroy()tixRoot = Tix.Tk()tixRoot.withdraw()app = MainWindow(tixRoot)app.mainloop()


The other solutions didn't work for me when I had 2 <tkinter.Entry>s but I found this:

import tkinter as tkfocus = 0def focus_in(event):    global focus    focus += 1def focus_out(event):    global focus    focus -= 1    if focus == 0:        root.destroy()root = tk.Toplevel()root.bind("<FocusIn>", focus_in)root.bind("<FocusOut>", focus_out)root.mainloop()

It has a counter for the number of times the window is focused. It destroys the window when the counter reaches 0.