Resize Tkinter Listbox widget when window resizes Resize Tkinter Listbox widget when window resizes tkinter tkinter

Resize Tkinter Listbox widget when window resizes


You want to read up on the geometry managers pack and grid, which lets you place widgets in a window and specify whether they grow and shrink or not. There's a third geometry manager, place, but it's not used very often.

Here's a simple example:

import tkinter as tkroot = tk.Tk()scrollbar = tk.Scrollbar(root, orient="vertical")lb = tk.Listbox(root, width=50, height=20, yscrollcommand=scrollbar.set)scrollbar.config(command=lb.yview)scrollbar.pack(side="right", fill="y")lb.pack(side="left",fill="both", expand=True)for i in range(0,100):    lb.insert("end", "item #%s" % i)root.mainloop()

If you wish to use grid instead of pack, remove the two lines that call pack and replace them with these four lines:

root.grid_rowconfigure(0, weight=1)root.grid_columnconfigure(0, weight=1)scrollbar.grid(row=0, column=1, sticky="ns")lb.grid(row=0, column=0, sticky="nsew")

Note that with grid you have to take the extra step to configure the weight for the row and column that contains the listbox, otherwise tkinter won't allocate any extra space to the widget.


The two main ways to allow a listbox to stretch when the window is resized are using the .pack() or .grid() methods.

SPECS:

Windows 7, Python 3.8.1, tkinter version: 8.6

.pack()

I found the easiest way to do this is by using the .pack() method, and utilizing the fill= & expand=True options.

import tkinter as tkroot=tk.Tk()                                              #Creates the main windowlistbox=tk.Listbox(root)                                  #Create a listbox widgetlistbox.pack(padx=10,pady=10,fill=tk.BOTH,expand=True)    #fill=tk.BOTH, stretch vertically and horizontally                                                          #fill=tk.Y, stretch vertically                                                          #fill=tk.X, stretch horizontally

If your listbox is placed in a frame, the frame will also need to use the fill= & expand=True options.

import tkinter as tkroot=tk.Tk()frame1=tk.Frame(root)frame1.pack(fill=tk.BOTH, expand=True)listbox=tk.Listbox(frame1)listbox.pack(padx=10,pady=10,fill=tk.BOTH,expand=True)

.grid()

The alternative technique is to use the .grid() method and utilize thesticky= option. In addition, you will need to configure the row and column that the listbox resides in.

import tkinter as tkroot=tk.Tk()  #create windowroot.columnconfigure(0,weight=1)    #confiugures column 0 to stretch with a scaler of 1.root.rowconfigure(0,weight=1)       #confiugures row 0 to stretch with a scaler of 1.listbox=tk.Listbox(root)listbox.grid(row=0,column=0,padx=5,pady=5,sticky='nsew')   

The sticky option causes the listbox to stick to the "North" (Top), "South" (Bottom), "East" (Right), and "West" (Left) sides of the cell as it is stretched.

If your listbox is placed within a frame, you will need to configure the column and row that the frame is in, along with configure the column and row that the listbox is in.

import tkinter as tkroot=tk.Tk()               #create windowroot.columnconfigure(0,weight=1)  root.rowconfigure(0,weight=1)frame1=tk.Frame(root)frame1.grid(row=0,column=0,sticky='nsew')frame1.columnconfigure(0,weight=1)frame1.rowconfigure(0,weight=1)listbox=tk.Listbox(frame1)listbox.grid(row=0,column=0,padx=5,pady=5,sticky='nsew')

.pack() & .grid()

Now there is one other technique, but some people frown on it. The third technique is to utilize the .pack() method and .grid() method in the same script. You can mix different geometry management method in the same script as long as only a one management type is used per container. You can see an example of this below.

import tkinter as tkroot=tk.Tk()               #create windowframe1=tk.Frame(root)                                #container: rootframe1.pack(fill=tk.BOTH,expand=True)                               frame1.columnconfigure(0,weight=1)frame1.rowconfigure(0,weight=1)frame1.rowconfigure(1,weight=1)listbox=tk.Listbox(frame1)                            #container: frame1listbox.grid(row=0,rowspan=2,column=0,padx=5,pady=5,sticky='nsew') btn1=tk.Button(frame1,text='Demo1')                   #container: frame1        btn1.grid(row=0,column=1, padx=5, pady=5)                          btn2=tk.Button(frame1,text='Demo2')                   #container: frame1     btn2.grid(row=1,column=1, padx=5, pady=5)                          frame2=tk.Frame(root)                                 #container: root frame2.pack()btn3=tk.Button(frame2,text='Demo3')                   #container: frame2btn3.grid(row=0,column=0)                                          

You can see above that the frames used .pack() while the listbox and buttons used .grid(). This was possible because the frames resided within the root container, while the listbox and buttons resided within their respective frames.


To check you tkinter version use:

import tkinter as tkprint(tk.TkVersion)

If you would like to learn about the differences between fill and expand, please see the following link.https://effbot.org/tkinterbook/pack.htm