Retrieve Tkinter listbox item by string, not by index

K

Kevin Walzer

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?
 
J

James Stroud

Kevin said:
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.


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

http://www.jamesstroud.com/
 
J

James Stroud

James said:
Kevin said:
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/
 
H

Hendrik van Rooyen

I'm trying to set the active item in a Tkinter listbox to my
application's currently-defined default font.

not sure if you can mix fonts in a listbox - the font option
when you create the listbox instance seems to apply globally
to all the lines in the box

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

Does this actually give you different fonts on each line? or just
a list of available font names, all displayed in the same font?
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?

not too sure I understand what you are trying to do - but consider:

idx = self.fontlist.curselection()

this is the index of the selection,
(as controlled by the user's fingers) so:

StringAtCurrSelection = self.fontlist.get(idx)

should be the string containing the text on the selected line

you can use self.fontlist.delete(idx) and
self.fontlist.insert(idx,SomeString) to make changes to the text.

But as to how you change this to display in a different font -
no can tell - don't know how, and not sure if its possible.
Only know that you can use configure to change the font
for all the lines in the box by changing the box's font option...

if, OTOH you are just trying to find where your default
lives in the box, why don't you look for it and remember
the index when you are populating the box?

something like this:

self.idx = 0
for item in self.fonts:
if item == mydefaultfont:
self.defidx = idx
self.fontlist.insert(idx, item)
idx += 1

then you can do whatever with the item that
lives at self.defidx afterwards...

hth - Hendrik
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top