I've encountered the problem, that I can not create a child widget of a child widget. I've tried using a class to create a window with widgets and alternatively a function to see if I don't understand something about how classes work, but the failure was the same.
I've boiled down the issue to the following code:
import tkinter as tk
root = tk.Tk()
root.geometry('900x400')
frame1=tk.LabelFrame(root, text="frame1",width=800, height=400, bg='blue', bd=5).pack()
labelframe1=tk.LabelFrame(frame1, text="labelframe1",width=300, height=300, bg='green', bd=15).pack()
labelframe2=tk.LabelFrame(frame1, text="labelframe2",width=300, height=300, bg='yellow', bd=15).pack()
button1 = tk.Button(labelframe1,text="text").pack()
I don't get errors with this code, but the outcome is the same. Only the child of root is created, but not the children of the root child.
How can I create "grandchild" widgets?
CodePudding user response:
In python, x().y()
returns the value of y()
. Thus, when you do tk.LabelFrame(...).pack()
it returns None
. Therefore, when you do tk.Button(labelframe1, ...)
it's the same as tk.Button(None, ...
, which causes the button to be a child of the root window.
Bottom line, it's a best practice to separate widget creation from widget layout. I also personally find that grouping layout code together makes the code much easier to understand. I think it's also a good practice to explicitly define which side the widget is being packed into.
frame1=tk.LabelFrame(root, text="frame1",width=800, height=400, bg='blue', bd=5))
labelframe1=tk.LabelFrame(frame1, text="labelframe1",width=300, height=300, bg='green', bd=15)
labelframe2=tk.LabelFrame(frame1, text="labelframe2",width=300, height=300, bg='yellow', bd=15)
button1 = tk.Button(labelframe1,text="text")
frame1.pack(side="top")
labelframe1.pack(side="top")
labelframe2.pack(side="top")
button1.pack(side="top").
button1 = tk.Button(labelframe1,text="text").pack()