I am writing a program to run batch files for various servers and so far everything is going fine. I mean the programs works and uses a simple GUI and all is well. Apart from when I give it a slightly longer name to display in the listbox it clips the end off. The code that Tkinter uses is below.
master = tk.Tk()
listbox = tk.Listbox(master, selectmode=tk.SINGLE)
keys = serverDict.keys()
for key in sorted(keys):
listbox.insert(tk.END, key)
button = tk.Button(master, text="Execute", command=execute)
listbox.pack()
button.pack()
tk.mainloop()
So basically it all works perfectly fine, I'm not getting any errors but it is a bit annoying the way it doesn't properly fit and I can't scroll. I know I can add scroll bars and make the window re-sizable and make the listbox fit the space it's given, but I would like it to work without having to resize stuff. I know it's not that important but it's just one of those things that I would love to work but can't figure out :/ .
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("")
This is based off of Oblivion's answer but I edited it so it worked for me.
I made a new listbox class that was based off of the original one but had a new function that I got from Oblivion's code. I then call that function and it makes the listbox an appropriate size.
class Listbox(tk.Listbox):
def autowidth(self,maxwidth):
f = font.Font(font=self.cget("font"))
pixels = 0
for item in self.get(0, "end"):
pixels = max(pixels, f.measure(item))
# bump listbox size until all entries fit
pixels = pixels + 10
width = int(self.cget("width"))
for w in range(0, maxwidth+1, 5):
if self.winfo_reqwidth() >= pixels:
break
self.config(width=width+w)
master = tk.Tk()
listbox = Listbox(master, selectmode=tk.SINGLE)
keys = serverDict.keys()
for key in sorted(keys):
listbox.insert(tk.END, key)
button = tk.Button(master, text="Execute", command=execute)
listbox.autowidth(250)
listbox.pack()
button.pack()
tk.mainloop()
tkListAutoWidth.py shows one way to do it:
http://svn.effbot.org/public/stuff/sandbox/tkinter/
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()
just give width and height 0 as below
listbox.config(width=0,height=0)