I have a grid layout in tkinter:
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
root.geometry('500x500')
root.rowconfigure(0, weight = 1)
root.rowconfigure(1, weight = 1)
root.rowconfigure(2, weight = 1)
root.columnconfigure(0, weight = 1)
root.columnconfigure(1, weight = 1)
root.columnconfigure(2, weight = 1)
root.columnconfigure(3, weight = 1)
ttk.Label(root, text = 'Area 1', background = 'red').grid(row = 0, column = 0, sticky = 'NSWE')
ttk.Label(root, text = 'Area 2', background = 'blue').grid(row = 1, column = 2, sticky = 'NSWE')
root.mainloop()
I know there are 4 columns and 3 rows but I am confused about the second and the last column (i.e. the ones without widgets) are narrower than the ones that have filled cells. When I measure it I get a default width for filled cells of about 215 while the empty ones only have 165. Is there a reason for this?
I suppose one way to fix it would be to add a label in column 1 and 3 with an empty string as text and give all labels a width. But that seems quite hacky, is there a better solution?
I guess I am ultimately confused about the fact that the width of a widget affects the width of a grid cell quite a bit. Can someone explain the logic behind it? I looked at lots of grid tutorials but haven't found one that talks about it.
CodePudding user response:
When I measure it I get a default width for filled cells of about 215 while the empty ones only have 165. Is there a reason for this?
The reason is that empty rows and empty columns have a default size of zero. In your code you're giving a non-zero weight to all columns, so after grid
has added the widgets, it divides the extra space up equally among the columns with a non-zero weight.
Lets say that the window has 200 extra pixels to allocate. Let's also say that the columns with widgets are 100 pixels each. Initially, column 0 will be 100 pixels wide, column 1 will be zero pixels wide, column 2 will be zero pixels, and column 3 will be 100 pixels.
Now, grid has to allocate the 200 extra pixels. That means that each column gets 50 pixels. Column 0 ends up being 150 pixels wide (100 50), column 1 will be 50 (0 50), and columns 2 and 3 are identical to 0 and 1.
I suppose one way to fix it would be to add a label in column 1 and 3 with an empty string as text and give all labels a width. But that seems quite hacky, is there a better solution?
If you give them each the same value for the uniform
option, and give them all the same value for weight
, all columns will be the same size.
root.columnconfigure(0, weight = 1, uniform="a")
root.columnconfigure(1, weight = 1, uniform="a")
root.columnconfigure(2, weight = 1, uniform="a")
root.columnconfigure(3, weight = 1, uniform="a")
Note: the value for uniform
is irrelevant. It can be any string. The important thing is that it needs to be the same string for all columns that you want to have the same size.
I guess I am ultimately confused about the fact that the width of a widget affects the width of a grid cell quite a bit.
I'm not sure what to say about that. That's how grid
is designed to work, and these defaults work quite well in practice.
For the official documentation of how grid
works see The grid algorithm in the tcl/tk man page for grid
.