Retrieve Tkinter listbox item by string, not by index

Discussion in 'Python' started by Kevin Walzer, Dec 22, 2006.

  1. Kevin Walzer

    Kevin Walzer Guest

    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
    Kevin Walzer, Dec 22, 2006
    #1
    1. Advertising

  2. Kevin Walzer

    James Stroud Guest

    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/
    James Stroud, Dec 23, 2006
    #2
    1. Advertising

  3. Kevin Walzer

    James Stroud Guest

    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/
    James Stroud, Dec 23, 2006
    #3
  4. "Kevin Walzer" <> wrote:


    > 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
    Hendrik van Rooyen, Dec 23, 2006
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Simon Prince
    Replies:
    2
    Views:
    3,320
    =?Utf-8?B?TWljaGFlbCBUYXlsb3I=?=
    Oct 19, 2004
  2. Replies:
    6
    Views:
    590
    Hendrik van Rooyen
    May 31, 2007
  3. Alan G Isaac
    Replies:
    5
    Views:
    385
    Colin J. Williams
    Aug 14, 2009
  4. haiwen
    Replies:
    3
    Views:
    161
    haiwen
    Jul 14, 2003
  5. Tomasz Chmielewski

    sorting index-15, index-9, index-110 "the human way"?

    Tomasz Chmielewski, Mar 4, 2008, in forum: Perl Misc
    Replies:
    4
    Views:
    275
    Tomasz Chmielewski
    Mar 4, 2008
Loading...

Share This Page