Python Tkinter Grid
When placing widgets on a frame or in your window directly, you need a system of placing those widgets into the window or frame and in relation to other widgets. Tkinter has 2 systems, pack and grid, in this post I will be demonstrating how the grid system works, why to use it, and with examples placing some widgets in a window.
What is grid and why use it
When using grid its logic essentially slices up the available space in your window or frame into little squares in an x y grid, hence the name 'grid'. Within that grid you can place widgets like buttons or dropdowns or other frames within a single grid square, or you can span multiple squares on a grid.
Grid is often referred to as the most flexible space management utility in tkinter, and while it takes a bit more code than 'pack' to place a widget, it will give you much more granular control in placement of elements.
Defining Fixed Size Grid to Auto Scale and Preserve Whitespace
If you want your widgets to get larger and smaller as the window is expanded or condensed, you will want to define a fixed width and height grid and specify a weight of 1 to each cell in the grid. This is simple enough, below is an example of defining an auto scaling 10x10 grid in a subclassed window.
from tkinter import Tk, Button
class MyWindow(Tk):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for x in range(10):
self.rowconfigure(x, weight=1)
self.columnconfigure(x, weight=1)
window = MyWindow()
window.mainloop()
The key point is lines 7-9 are configuring the 10x10 grid.
Then if we add 2 buttons inside the window object to demonstrate the scaling like below.
class MyWindow(Tk):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for x in range(10):
self.rowconfigure(x, weight=1)
self.columnconfigure(x, weight=1)
btn1 = Button(self, text='btn1')
btn2 = Button(self, text='btn2')
btn1.grid(row=0, column=1, sticky='nesw')
btn2.grid(row=0, column=2, sticky='nesw')
You can see when running that code that it has 2 buttons with whitespace around each button and as you expand and contract the window the buttons scale and so does the whitespace.
In most cases I always define an auto scaling grid in my windows and frames because I enjoy the freedom it gives to make the windows larger and smaller.
Using Grid to Place Widgets
Placing widgets in the grid is the same regardless of scaling, and in the example above I demonstrated defining and adding a button but to add onto that I will explain the keyword arguments you can specify using the example below.
class MyWindow(Tk):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for x in range(10):
self.rowconfigure(x, weight=1)
self.columnconfigure(x, weight=1)
btn1 = Button(self, text='btn1')
btn1.grid(row=1, column=1, rowspan=1, columnspan=1, sticky='nesw')
And we will focus on this line.
btn1.grid(row=1, column=1, rowspan=1, columnspan=1, sticky='nesw')
Lets walk through how this is placing the button on the grid.
- row=1 -- Place the widget in row index 1 (This is the second row because it is 0 indexed)
- column=1 -- Place the widget in column index 1 (This is the second column because the grid is 0 indexed)
- rowspan=1 -- From the row where the widget was placed, span it 1 row. This makes it take up 2 rows
- columnspan=1 -- From the column where the widget was placed, span it 1 column. This makes it take up 2 columns
- sticky='nesw' -- Expand the widget in its placed area in the directions of North, East, South, and West.
The key to understand about the sticky directions is they are cardinal directions in the confines of your monitor. Meaning North is up, East is right, South is down, and West is left. So if you wanted your widget to take up all space to the left and right but not up and down you would set sticky to 'ew'
.
This has been a basic introduction to Tkinter's grid system and placing widgets using it. If things are unclear or you feel it is missing please leave a comment so I can clear things up.