Search code examples
pythonclasstkinterinstanceparent

Python Tkinter parenting problem of an instance


i have frame class A and B, B class is "created" in A class, A is parented as "self".

problem: result show that B is outside A. no error raised.

in another post answered that widget returned None. so root window is chosen as default.

but print(instance B) return ".!instance B name" not None.

this is the code:

import tkinter as tk

# class B
class Frm_btn(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, width=24, height=24, bg="green")
        self.parent=parent

# class A
class Frm_tool(tk.Frame):
    def __init__(self):
        tk.Frame.__init__(self, width=48, height=48, bg="blue")
        self.parent=win

        # instance of class B
        self.frm_btn=Frm_btn(self)
        self.frm_btn.pack()

        print(self)# return ".!frm_tool"
        print(self.frm_btn)# return ".!frm_btn"


win=tk.Tk()
win.configure(bg="red")

# instance of class A
frm_tool=Frm_tool()
frm_tool.pack()

win.mainloop()

Solution

  • You seem a bit confused. The positional argument master is set by default or as the first argument. Example:

    b = tk.Button() #master is the root window by default 
    b.pack()
    
    b2= tk.Button(my_frame) #master is set to my_frame
    

    The constructor returns a reference not None as stated. None is returned by every function that dosent returns something else, that's how python works.

    For example:

    b = tk.Button()
    c = b.pack()
    print(c)
    

    Also note that if you assign a variable to something returned by functions or methods the last returned value is assigned to your variable. So this code:

    b = tk.Button().pack()
    

    Is equally to this code:

    b = tk.Button() #returns a reference
    b = b.pack() #returns None
    

    As @MegaIng already pointed out to you. If you want to set the master in a inheritanced class you have to explicit do so. For example:

    class Frm_btn(tk.Frame): 
        def __init__(self, parent): 
            tk.Frame.__init__(self,parent, width=24, height=24, bg="green") 
            self.parent=parent