Reputation: 197
I'm trying to use the grid() method to position two frames - one at the top of the window, and one on the left of the window.
I've been successful in doing that with the pack() method - so this is getting me what I want:
This works with the pack() method, which works great:
import tkinter as tk
main_window = tk.Tk()
main_window.geometry("480x420")
frame_top = tk.Frame(main_window, bg="yellow", height=50)
frame_left = tk.Frame(main_window, bg="orange", width=50)
frame_top.pack(side=tk.TOP, fill=tk.X)
frame_left.pack(side=tk.LEFT, fill=tk.Y)
main_window.mainloop()
However, I'm trying to learn more about the grid method, so when I attempt to do the same thing with the grid() method, it ends up looking like this:
My code with the grid() method (something is wrong here):
import tkinter as tk
main_window = tk.Tk()
main_window.geometry("480x420")
frame_top = tk.Frame(main_window, bg="yellow", height=50)
frame_left = tk.Frame(main_window, bg="orange", width=50)
frame_top.grid(row=0, column=0, sticky=tk.W+tk.N+tk.E)
frame_left.grid(row=1, column=0, sticky=tk.W+tk.S+tk.N)
main_window.mainloop()
What am I doing wrong with the grid method? How can I make it end up looking the same way it does when I use pack()?
Upvotes: 0
Views: 123
Reputation: 385910
By default, grid
won't allocate any extra space to a widget unless told to do so. Since your widgets aren't very wide, there's a lot of unused extra space.
You can tell grid what to do with the extra space by giving rows and columns "weight". The weight tells grid how to allocate extra space. A good rule of thumb is that you should always give at least one row and one column a weight for every widget that uses grid
to manage its children.
In your specific case, adding the following code will give you the same appearance as the one where you use pack
:
main_window.grid_rowconfigure(1, weight=1)
main_window.grid_columnconfigure(0, weight=1)
This tells grid
that any extra vertical space should be given to row 1, and any extra horizontal space should go to column 0
However, that's just a quick hack to illustrate. I'm guessing you're going to want to put other widgets in the large white space. If that's the case, I think the better solution to give all of the weight to row 1 and column 1. Then, make sure that the yellow frame is told to span two columns. I also recommend nearly always having widgets be "sticky" to all sides. Otherwise, you may end up with white space that you don't want.
frame_top.grid(row=0, column=0, sticky="nsew", columnspan=2)
frame_left.grid(row=1, column=0, sticky="nsew")
main_window.grid_rowconfigure(1, weight=1)
main_window.grid_columnconfigure(1, weight=1)
The next step would be to put a frame in row 1, column 1. You can then add widgets into this frame without affecting the main layout -- inside the frame you can use pack
or grid
and that layout will be independent of the layout in the window as a whole.
Upvotes: 1
Reputation: 12672
Only use .grid()
can not do it directly.
You need to set the rowspan
and columnspan
(If you want it always full one row or one column).
And set columnconfigure
and rowconfigure
to make it responsive.It is a little complex.
import tkinter as tk
main_window = tk.Tk()
main_window.geometry("480x420")
frame_top = tk.Frame(main_window, bg="yellow", height=50)
frame_left = tk.Frame(main_window, bg="orange", width=50)
# always full one row
frame_top.grid(row=0, column=0, columnspan=999, sticky=tk.W+tk.N+tk.E)
# always full one column
frame_left.grid(row=1, column=0, rowspan=999, sticky=tk.W+tk.S+tk.N)
# make it responsive
main_window.grid_rowconfigure(0,weight=0)
main_window.grid_rowconfigure(1,weight=1)
main_window.grid_columnconfigure(0,weight=0)
main_window.grid_columnconfigure(1,weight=1)
main_window.mainloop()
Upvotes: 1