Creating a pull-down list with Tkinter
Michael P. Reilly
arcege at shore.net
Wed May 5 18:18:19 EDT 1999
Ben Gertzfield <che at debian.org> wrote:
: After reading through the meagre documentation available for Tkinter,
: I've stumped myself. Is there any module available that will give
: me a pull-down list, similar to what appears in tkFileDialog, or
: any of the zillions of pull-down lists you see on web pages?
: I'm trying to make a graphical front-end to my ID3 MP3 info tag
: manipulator Python class, but Listbox is inappropriate when there
: are ~150 selections possible for one of the fields (the genre
: of the song) and I need to let the user select from one of them.
: How can I create a pull-down list with Tkinter?
I'm not sure if you mean a scrolled listbox or an extensible menu button.
I've created the latter (based a bit on a similar widget in tkdiff in
the TkCVS package).
#!/usr/local/bin/python
from Tkinter import *
import os
class Popup(Menubutton):
def __init__(self, master=None, list=None):
Menubutton.__init__(self, master, direction='right', relief=RAISED)
menu = self['menu'] = Menu(self)
l = len(list)
if l <= 10:
for p in xrange(l):
item = list[p]
menu.add_command(label='%d %s' % (p+1, str(item)))
else:
from math import sqrt
per_level = int(sqrt(l))
how_many, extra = divmod(l, per_level)
if extra:
how_many = how_many + 1
p = 0
for i in xrange(how_many):
submenu = Menu(self)
menu.add_cascade(label=`(i*per_level)+1`, menu=submenu)
for j in xrange(min(l-p, per_level)):
item = list[p]
submenu.add_command(label='%d %s' % (p+1, str(item)))
p = p + 1
if __name__ == '__main__':
m = Popup(None, os.listdir(os.environ['HOME']))
m['text'] = 'What?'
Button(text='Quit', command=m.quit).pack()
m.pack()
m.mainloop()
This creates a simple button which when pressed gives you a pop-up menu
of your home directory. If you have more than ten files in your home
directory, then you will get a submenu for each N files. The widget
isn't complete, but it suffices.
If you wanted a scrolled listbox, that is a bit easier:
class ScrolledListbox(Listbox):
def __init__(self, master, cnf={}, **kw):
from Tkinter import _cnfmerge
if kw:
cnf = _cnfmerge((cnf, kw))
else:
cnf = _cnfmerge(cnf)
frame = Frame(master, cnf)
Listbox.__init__(self, frame, relief=SUNKEN)
scroll = Scrollbar(master, relief=SUNKEN, command=self.yview)
scroll.pack(side=RIGHT, fill=Y, expand=YES)
self['yscrollcommand'] = scroll.set
self.pack(fill=BOTH, expand=YES)
# redefine "pack", "place" and "grid" to be the frame instance's methods
self.pack = frame.pack
self.place = frame.place
self.grid = frame.grid
Now use instances of ScrolledListbox as a regular listbox.
-Arcege
More information about the Python-list
mailing list