By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,898 Members | 1,198 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,898 IT Pros & Developers. It's quick & easy.

Retrieve Tkinter listbox item by string, not by index

P: n/a
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?
--
Kevin Walzer
Code by Kevin
http://www.codebykevin.com
Dec 22 '06 #1
Share this Question
Share on Google+
3 Replies


P: n/a
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.
--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
Dec 23 '06 #2

P: n/a
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/
Dec 23 '06 #3

P: n/a
"Kevin Walzer" <kw@codebykevin.comwrote:

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

Dec 23 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion.