Retrieve Tkinter listbox item by string, not by index

James Stroud jstroud at mbi.ucla.edu
Fri Dec 22 21:04:37 EST 2006


James Stroud wrote:
> Kevin Walzer wrote:
> 
>> I'm trying to set the active item in a Tkinter listbox to my 
>> application's currently-defined default font.
>>
>> Here's how I get the fonts loaded into the listbox:
>>
>>  self.fonts=list(tkFont.families())
>>  self.fonts.sort()
>>
>>   for item in self.fonts:
>>             self.fontlist.insert(END, item)   #self.fontlist is the 
>> ListBox instance
>>
>>
>> So far, so good. But I don't know how to set the active selection in 
>> the listbox to the default font. All the methods for getting or 
>> setting a selection in the listbox are based on index, not a string. 
>> And using standard list search methods like this:
>>
>>        if "Courier" in self.fontlist:
>>             print "list contains", value
>>         else:
>>             print value, "not found"
>>
>> returns an error:
>>
>> TypeError: cannot concatenate 'str' and 'int' objects
>>
>> So I'm stuck. Can someone point me in the right direction?
> 
> 
> I would keep a separate data structure for the fonts and update the 
> scrollbar when the list changed. This would help to separate the 
> representation from the data represented. Here is a pattern I have found 
> most useful and easy to maintain:
> 
> # untested
> class FontList(Frame):
>   def __init__(self, *args, **kwargs):
>     Frame.__init__(self, *args, **kwargs)
>     self.pack()
>     self.fonts = list(kwargs['fonts'])
>     self.default = self.fonts.index(kwargs['default_font'])
>     self.lb = Listbox(self)
>     # add scrollbar for self.lb, pack scrollbar
>     # pack self.lb
>     self.set_bindings()
>     self.update()
>   def set_bindings(self):
>     # put your bindings and behavior here for FontList components
>   def update(self):
>     self.lb.delete(0, END)
>     for f in self.fonts:
>       self.lb.insert(f)
>     self.highlight()
>   def highlight(self):
>     index = self.default
>     self.lb.see(index)
>     self.lb.select_clear()
>     self.lb.select_adjust(index)
>     self.lb.activate(index)
>   def change_font(self, fontname):
>     self.default = self.fonts.index(fontname)
>     self.highlight()
>   def add_font(self, fontname, index=None):
>     if index is None:
>       self.fonts.append(fontname)
>     else:
>       self.fonts.insert(index, fontname)
>     self.update()
>   # other methods for adding multiple fonts or removing them, etc.
> 
> 

I overlooked that you will actually want to remove "fonts" and 
"default_fonts" from kwargs before initializing with Frame:

# untested
class FontList(Frame):
   def __init__(self, *args, **kwargs):
     self.fonts = list(kwargs['fonts'])
     self.default = self.fonts.index(kwargs['default_font'])
     kwargs.pop('fonts')
     kwargs.pop('default_font')
     Frame.__init__(self, *args, **kwargs)
     self.pack()
     self.lb = Listbox(self):
     # etc.

James

-- 
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/



More information about the Python-list mailing list