Tkinter Tutorial - Layout Management
In the previous sections, we have introduced several Tkinter widget types, such as label, button, drop-down menu, etc. Meanwhile, we have also mentioned briefly how to layout these widgets in the program window. This is the key point that you will learn in this section - Tkinter’s geometry management methods.
Tkinter has three geometry management methods, that is, pack
, grid
, and place
. Let’s go through them one by one.
Tkinter pack
Layout Method
pack
method, as literally indicated, packs the widget to the window frame after it is created. We come across this layout method in the section Tkinter Label where all the pack
options are also listed.
We will show you how to layout widgets with pack
method (also its options). A few examples help to demonstrate the right configuration.
Tkinter pack
Layout - Relative Position
import tkinter as tk
app = tk.Tk()
app.geometry("300x200")
buttonW = tk.Button(app, text="West", width=15)
buttonW.pack(side="left")
buttonE = tk.Button(app, text="East", width=15)
buttonE.pack(side="right")
app.mainloop()
Run the program, you will get a window like this,
As you can see, buttonWest
snaps to the left side of the window and buttonEast
snaps to the right side of the window. You can try to scale the size of the window below, but you will find that they will still cling to the sides of the window and the relative position will not change.
buttonW.pack(side="left")
side
has four options -
top
bottom
left
right
It places the widget on the side
of the window. As illustrated in the example, buttonW
is allocated on the left side of the window, because side='left'
, while buttonE
is on the right side of the window, because side='right'
.
Now we have an interesting scenario, what happens if two widgets have the same side
property, how the layout will be?
Try to answer it yourself, or check it by running the following codes.
import tkinter as tk
app = tk.Tk()
app.geometry("300x200")
buttonW = tk.Button(app, text="West", width=15)
buttonW.pack(side="left")
buttonE1 = tk.Button(app, text="East 1", width=15)
buttonE1.pack(side="right")
buttonE2 = tk.Button(app, text="East 2", width=15)
buttonE2.pack(side="right")
app.mainloop()
Tkinter pack
to Add Widget Internal and External Padding
In some cases, you need to add some padding inside or outside the widget so that there is less congestion between the widgets, and also between the widget text and the widget boundaries. Now, you need options as padx
, pady
, ipadx
and ipadx
.
import tkinter as tk
app = tk.Tk()
app.geometry("300x200")
buttonW = tk.Button(app, text="West")
buttonW.pack(side="left", ipadx=20, padx=30)
buttonE = tk.Button(app, text="East")
buttonE.pack(side="right", ipadx=20, padx=30)
app.mainloop()
Both buttons add inner 20 units padding and outer 30 units in the x
, and the unit is pixel but not the width of one character.
Tkinter pack
Layout Filling in X, Y Direction
The following code implementation could automatically fill the widget dimension to the same width or the same height as the window, and when you zoom the window, the size of the control can automatically change with the size of the window.
import tkinter as tk
app = tk.Tk()
app.geometry("300x200")
buttonX = tk.Button(app, text="Fill X", bg="red", height=5)
buttonX.pack(fill="x")
buttonY = tk.Button(app, text="Fill Y", bg="green", width=10)
buttonY.pack(side="left", fill="y")
app.mainloop()
butonX.pack(fill='x')
means buttonX
will fill the width of the whole window. Similarly, fill='y'
will fill the height of the whole window, and meanwhile fill='both'
will fill both the width and height.
Tkinter pack
Layout Option expand
- Automatically Expand
Above fill=
option will automatically fill the widget in x
and/or y
direction when the window size is modified. Another similar requirement is how to automatically display all the contents if the widget includes multiple options, like a list?
import tkinter as tk
import calendar
app = tk.Tk()
buttonX = tk.Button(app, text="Label ", bg="blue", height=5)
buttonX.pack(fill="x")
listboxA = tk.Listbox(app, width=10)
listboxA.pack(fill="both", expand=1)
for i in range(1, 13):
listboxA.insert(tk.END, calendar.month_name[i])
app.mainloop()
When expand=True
or expand=1
, the list box will list all the items, from January
to December
as demonstrated in the above example.
If expand
is set to be False
, then the list box only shows the first 10 items by default. You need to use the mouse or direction keys to show the hidden items after the list box is selected.
listboxA.pack(fill="both", expand=0)
expand=0
disables the list box to automatically show all items.
Tkinter grid
Layout Method
Tkinter grid
is another and also the most important layout geometry method. This is the one you should learn if you only want to learn one single method among all geometry managers.
grid
is often used in dialog boxes, and you could place the widgets based on the position coordinates of the grid. grid
layout method could have stable relative positions of all widgets.
The following example will create a relatively complicated GUI compared to the above examples, which uses as many options of grid
as possible that will be explained in the next sections.
import tkinter as tk
app = tk.Tk()
labelWidth = tk.Label(app, text="Width Ratio")
labelWidth.grid(column=0, row=0, ipadx=5, pady=5, sticky=tk.W + tk.N)
labelHeight = tk.Label(app, text="Height Ratio")
labelHeight.grid(column=0, row=1, ipadx=5, pady=5, sticky=tk.W + tk.S)
entryWidth = tk.Entry(app, width=20)
entryHeight = tk.Entry(app, width=20)
entryWidth.grid(column=1, row=0, padx=10, pady=5, sticky=tk.N)
entryHeight.grid(column=1, row=1, padx=10, pady=5, sticky=tk.S)
resultButton = tk.Button(app, text="Get Result")
resultButton.grid(column=0, row=2, pady=10, sticky=tk.W)
logo = tk.PhotoImage(file="python.gif")
labelLogo = tk.Label(app, image=logo)
labelLogo.grid(
row=0,
column=2,
columnspan=2,
rowspan=2,
sticky=tk.W + tk.E + tk.N + tk.S,
padx=5,
pady=5,
)
app.mainloop()
Tkinter grid
column
and row
Options
labelWidth.grid(column=0, row=0, ipadx=5, pady=5, sticky=tk.W + tk.N)
Every widget shall be placed in the absolute cell in the grid
layout method. The cell coordinate is determined by column
and row
.
labelWidth
widget is placed in the cell of position (0, 0)
. The coordinate starts from the upper left corner of the window.
ipadx
, ipady
, padx
and pady
options are the same as those in pack
method.
Tkinter grid
sticky
Option
sticky
determines how the widget sticks to the cell when the widget is smaller than the cell.
sticky |
Meaning |
---|---|
W |
stick to left |
E |
stick to right |
N |
stick to top |
S |
stick to bottom |
The default sticky
option is center, that is W+E+N+S
.
Tkinter columnspan
and rowspan
Options
labelLogo.grid(
row=0,
column=2,
columnspan=2,
rowspan=2,
sticky=tk.W + tk.E + tk.N + tk.S,
padx=5,
pady=5,
)
The cell coordinate of labelLogo
is (column=2, row=0)
and the size of logo is relatively large, therefore it is allocated with cell size of 2x2
. columnspan=2
and rowspan=2
means the widget has spans of two cells both in X
and Y
directions starting from the position of the widget.
Tkinter place
Method
Tkinter place
method places the widget in an absolute or relative position in the window. We still use the same approach as above to introduce the options of this layout method.
import tkinter as tk
app = tk.Tk()
app.geometry("300x300")
labelA = tk.Label(app, text="Label (0, 0)", fg="blue", bg="#FF0")
labelB = tk.Label(app, text="Label (20, 20)", fg="green", bg="#300")
labelC = tk.Label(app, text="Label (40, 50)", fg="black", bg="#f03")
labelD = tk.Label(app, text="Label (0.5, 0.5)", fg="orange", bg="#0ff")
labelA.place(x=0, y=0)
labelB.place(x=20, y=20)
labelC.place(x=40, y=50)
labelD.place(relx=0.5, rely=0.5)
app.mainloop()
Tkinter place
Absolute Position
labelA.place(x=0, y=0)
labelB.place(x=20, y=20)
x=
and y=
options in place
determines the absolute positions of the widget, which have the unit as pixel. For example, lableB.place(x=20, y=20)
means labelB
is placed in the coordinate of (20, 20)
.
Tkinter place
Relative Position
The drawback of the absolute position is that if there are other widgets in the window placed with relative positions, when the window is zoomed, the widget using the absolute position layout will possibly have the overlap with other widgets.
place
layout method also has the relative position option, that is,
labelD.place(relx=0.5, rely=0.5)
Where relx
and rely
are in the range of 0.0~1.0
. It is the relative percentage of the widget position to the window size.
For example, relx=0.5, rely=0.5
means the widget is placed in the 50% of the window width and 50% of the window height.
relx=1.0
is the right boundary of the window, and rely=1.0
is the bottom boundary of the window.
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook