57

I've been searching different websites trying to find out what weight does in tkinter. I got this from TkDocs:

Every column and row has a "weight" grid option associated with it, which tells it how much it should grow if there is extra room in the master to fill. By default, the weight of each column or row is 0, meaning don't expand to fill space.

Could someone please put this into some context for me, as I'm struggling to understand what it does. I've experimented with the following code, and it just seems to move things across the page as I change the values.

try:
    import tkinter
except ImportError:  # python 2
    import Tkinter as tkinter

import os

mainWindow = tkinter.Tk()

mainWindow.title("Grid demo")
mainWindow.geometry('640x480-8-200')

label = tkinter.Label(mainWindow, text="tkinter grid demo")
label.grid(row=0, column=0, columnspan=3)

mainWindow.columnconfigure(0, weight=1)
mainWindow.columnconfigure(1, weight=1)
mainWindow.columnconfigure(2, weight=3)
mainWindow.columnconfigure(3, weight=3)
mainWindow.columnconfigure(4, weight=3)
mainWindow.rowconfigure(0, weight=1)
mainWindow.rowconfigure(1, weight=10)
mainWindow.rowconfigure(2, weight=1)
mainWindow.rowconfigure(3, weight=3)
mainWindow.rowconfigure(4, weight=3)

fileList = tkinter.Listbox(mainWindow)
fileList.grid(row=1, column=0, sticky='nsew', rowspan=2)
fileList.config(border=2, relief='sunken')

for zone in os.listdir('/Windows/System32'):
    fileList.insert(tkinter.END, zone)
mainWindow.mainloop()
Fred
  • 750
  • 1
  • 7
  • 14

1 Answers1

112

In the simplest terms possible, a non-zero weight causes a row or column to grow if there's extra space. The default is a weight of zero, which means the column will not grow if there's extra space.

Consider the following code, which creates a window larger than the widgets that are inside, and for which no columns have weight:

import tkinter as tk

root = tk.Tk()
root.geometry("200x100")

f1 = tk.Frame(root, background="bisque", width=10, height=100)
f2 = tk.Frame(root, background="pink", width=10, height=100)

f1.grid(row=0, column=0, sticky="nsew")
f2.grid(row=0, column=1, sticky="nsew")

root.grid_columnconfigure(0, weight=0)
root.grid_columnconfigure(1, weight=0)

root.mainloop()

Note: columnconfigure is an alias for grid_columnconfigure. I used the longer form here because I think it is more clear.

This is what the window looks like:

window with no weights applied

The reason it looks that way is because tkinter has been told not to give any of the columns any extra space, so the extra space goes unused to the right.

Now, change the code so that we give a weight to just one column:

root.grid_columnconfigure(0, weight=1)

When we restart, we now have a window that looks like this:

window with weight on first column only

What happened? Because column zero had a weight of one, tkinter gave the extra space to this column. You could have set the weight to 1, 100, 100000 and you would get the same result. In this case, all of the extra space goes to this one column.

What happens if you give both columns a weight? The extra space is divided between the columns proportional to their weight. For example, let's say you want a navigation area on the left that takes up 1/4 of the screen and the main area should take up 3/4 of the screen (a 1:3 ratio).

Let's change the weights to look like this:

root.grid_columnconfigure(0, weight=1)
root.grid_columnconfigure(1, weight=3)

Since both columns have weight, extra space is given to both columns. For every four pixels of extra space, column 0 will get 1 and column 1 will get the other 3.

window with weight given to both columns

What's more, if you interactively resize the window, the proportion is preserved as much as possible. Here's the same window that I manually resized to be much wider:

window after resizing

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • 2
    Using "weight" gives me an error that reads: "TclError: bad option "-weight": must be -column, -columnspan, -in, -ipadx, -ipady, -padx, -pady, -row, -rowspan, or -sticky" – Korzak Oct 25 '18 at 17:42
  • 4
    @Korzak: correct. `weight` is an option for `rowconfigure` and `columnconfigure`, but not for `grid`. Based on the error message, you tried to use it with `grid` (or `grid_configure`) – Bryan Oakley Oct 25 '18 at 18:00
  • Thank you! I am using 'grid'. I'm trying to make a label span two rows, but it's not working. When I use 'sticky=N + S', it still doesn't span two rows. I've read like 30 articles and threads and still can't solve it. I'll keep looking. Thanks!! – Korzak Oct 26 '18 at 13:42
  • @BryanOakley If 0 is the default weight, could you explain why explicitely setting `weight=0` makes a column still expand ? – Christoph Frings Apr 26 '19 at 13:59
  • @ChristophFrings: explicitly setting the weight to zero should have absolutely no effect. It will continue to behave as if it had the default weight. – Bryan Oakley Apr 26 '19 at 14:43
  • @BryanOakley Very strange... I recently had an issue with that but can't manage to duplicate it. Must have made some strange stuff at other places. – Christoph Frings Apr 26 '19 at 15:29
  • @BryanOakley - very clear answer - thank you! – Aldo Dec 11 '20 at 15:51