Search code examples
pythonuser-interfacetkinterevent-driven

How to access a button's parent in Tkinter without writing class?


Is there any way to find a widget's parent (specifically button) without saving the parent in an object attribute?

but = Button(main_window, text = "close window!")
but.bind("<Button-1>", btn_handler)

def btn_handler(e):
    e.parent().destroy() # I need something like this!
    # e.parent() ==>> main_window
    # without writing class and defining self.parent ...

I am searching internet for several hours and I didn't find proper answer.


Solution

  • You can use but.master to access the parent of the but object.

    To get the container widget of a widget that's handling a callback, you can do:

    def callback(evt):
        handling_widget = evt.widget
        parent_of_handling_widget = handling_widget.master
        # or evt.widget.master
        parent_of_handling_widget.destroy()
    

    That said, I'm not exactly sure why you're trying to avoid using a custom class. It's a natural solution to your problem.

    import tkinter
    from tkinter import ttk
    
    class MyButton(ttk.Button):
    
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.configure(command=self.callback)
    
        def callback(self):
            self.master.destroy()
    
    tk = tkinter.Tk()
    b = MyButton(tk, text="close window!")
    b.pack()  # or whatever geometry manager you're using
    
    # we're done!