How to fit Tkinter listbox to contents

13,945

Solution 1

Resetting the listbox width worked for me. I used the Oblivion's answer and noticed that the width is always zero.

listbox = tk.Listbox(master, selectmode=tk.SINGLE)
listbox.config(width=0)

I also recommend to reset the root window geometry after reloading a content of the list. Otherwise if user manually extends a window the window would stop accommodate size of its content.

root.winfo_toplevel().wm_geometry("")

Solution 2

just give width and height 0 as below

listbox.config(width=0,height=0)

Solution 3

tkListAutoWidth.py shows one way to do it.

Edit:

So you might have something along the lines of,

import tkinter as tk
from tkinter import font


class NewListbox(tk.Listbox):

    def autowidth(self, maxwidth=100)
        autowidth(self, maxwidth)


def autowidth(list, maxwidth=100):
    f = font.Font(font=list.cget("font"))
    pixels = 0
    for item in list.get(0, "end"):
        pixels = max(pixels, f.measure(item))
    # bump listbox size until all entries fit
    pixels = pixels + 10
    width = int(list.cget("width"))
    for w in range(0, maxwidth+1, 5):
        if list.winfo_reqwidth() >= pixels:
            break
        list.config(width=width+w)


if __name__ == "__main__":

    master = tk.Tk()
    listbox = NewListbox(master, selectmode=tk.SINGLE)

    # ...
    # ...
    keys = serverDict.keys()
    for key in sorted(keys):
        listbox.insert("end", key)

    listbox.pack()

    button = tk.Button(master, text="Execute", command=execute)
    button.pack()

    listbox.autowidth()

    master.mainloop()
Share:
13,945
ftm
Author by

ftm

Updated on July 26, 2022

Comments

  • ftm
    ftm almost 2 years

    I'm adding strings to a listbox using the code below. When I run the code and the window opens, the longer strings get clipped as the window is not large enough (see screenshot). I have tried making the window resizeable and adding scroll bars but I was wondering if there was a way to automatically size it to fit the content.

    master = tk.Tk()
    listbox = tk.Listbox(master, selectmode=tk.SINGLE)
    
    games = ["Garry's Mod", "Mount and Blade: Warband", "Tekkit"]
    for game in sorted(games):
        listbox.insert(tk.END, game)
    
    button = tk.Button(master, text="Execute", command=execute)
    
    listbox.pack()
    button.pack()
    tk.mainloop()
    

    example of clipped listbox