1

I seek to bind a close window function to a Tkinter child window. I have been able to implement the binding process for the parent, but I am struggling to enact the binding implementation for the child window.

Using the example set out in this question I have attempted to bind the close function to the Escape key, without success nor an error message.

import tkinter as tk


def close(self):
    self.top.destroy()

class ChildWindow:
    def __init__(self, master):
        self.top = tk.Toplevel(master)
        self.frame = tk.Frame(self.top)
        self.frame.pack()

        self.frame.bind("<Escape>",lambda: close(self))        

        self.close_button = tk.Button(self.frame, text="Close", command=self.top.destroy)
        self.close_button.pack()

class MainWindow:
    def __init__(self, master):
        self.master = master
        self.frame = tk.Frame(self.master)

        self.about_button = tk.Button(self.frame, text="Open child window", command=self._open_child_window)
        self.about_button.pack()
        self.frame.pack()

    def _open_child_window(self):
        self.about_window = ChildWindow(self.master)

root = tk.Tk()
lf = MainWindow(root)
root.mainloop()

stovfl
  • 14,998
  • 7
  • 24
  • 51
EQNX
  • 131
  • 10
  • 1
    ***"self.frame.bind(..."***: I suppose, a `Frame` will never get the keyboard foucs, therefore get never a key event. – stovfl Nov 23 '19 at 19:43
  • @stovfl in your view is there any attribute of the child object that would get the keyboard focus and that I could then bind the close function to? – EQNX Nov 23 '19 at 19:48
  • 2
    @EQNX I would try `root.bind(...`, as `root` should get all events. In your `def close(...` you need a condition like `if ChildWindow is .shown:` Read about [Widget.grab_set-method](http://effbot.org/tkinterbook/widget.htm#Tkinter.Widget.grab_set-method) – stovfl Nov 23 '19 at 19:51
  • 1
    @stovfl ```root.bind(...,``` did the trick – EQNX Nov 23 '19 at 19:57
  • @EQNX OK, read [Widget.winfo_visual-method](http://effbot.org/tkinterbook/widget.htm#Tkinter.Widget.winfo_visual-method) – stovfl Nov 23 '19 at 19:58

1 Answers1

1

As per @stovfl's suggestion I changed the bind be an attribute of the root not the self.frame

This captured the keyboard event and successfully called the close(self) function.

import tkinter as tk

def close(self):
    self.top.destroy()

class ChildWindow:
    def __init__(self, master):
        self.top = tk.Toplevel(master)
        self.frame = tk.Frame(self.top)
        self.frame.pack()

        root.bind("<Escape>",lambda event: close(self))        

        self.close_button = tk.Button(self.frame, text="Close", command=self.top.destroy)
        self.close_button.pack()

    def close(self, event=None):
        print("destroy arg")
        self.root.destroy()


class MainWindow:
    def __init__(self, master):
        self.master = master
        self.frame = tk.Frame(self.master)



        self.about_button = tk.Button(self.frame, text="Open child window", command=self._open_child_window)
        self.about_button.pack()
        self.frame.pack()

    def _open_child_window(self):
        self.about_window = ChildWindow(self.master)

root = tk.Tk()
lf = MainWindow(root)
root.mainloop()
EQNX
  • 131
  • 10