back next

The tkinter Listbox Widget

The Listbox widget is a standard tkinter widget used to display a list of alternatives. The listbox can only contain text items, and all items must have the same font and color. Depending on the widget configuration, the user can choose one or more alternatives from the list.

When to use the Listbox Widget

Listboxes are used to select from a group of textual items. Depending on how the listbox is configured, the user can select one or many items from that list.

Patterns #

When you first create the listbox, it is empty. The first thing to do is usually to insert one or more lines of text. The insert method takes an index and a string to insert. The index is usually an item number (0 for the first item in the list), but you can also use some special indexes, including ACTIVE, which refers to the “active” item (set when you click on an item, or by the arrow keys), and END, which is used to append items to the list.

from tkinter import *

master = Tk()

listbox = Listbox(master)
listbox.pack()

listbox.insert(END, "a list entry")

for item in ["one", "two", "three", "four"]:
    listbox.insert(END, item)

mainloop()

To remove items from the list, use the delete method. The most common operation is to delete all items in the list (something you often need to do when updating the list).

listbox.delete(0, END)
listbox.insert(END, newitem)

You can also delete individual items. In the following example, a separate button is used to delete the ACTIVE item from a list.

lb = Listbox(master)
b = Button(master, text="Delete",
           command=lambda lb=lb: lb.delete(ANCHOR))

The listbox offers four different selection modes through the selectmode option. These are SINGLE (just a single choice), BROWSE (same, but the selection can be moved using the mouse), MULTIPLE (multiple item can be choosen, by clicking at them one at a time), or EXTENDED (multiple ranges of items can be chosen, using the Shift and Control keyboard modifiers). The default is BROWSE. Use MULTIPLE to get “checklist” behavior, and EXTENDED when the user would usually pick only one item, but sometimes would like to select one or more ranges of items.

lb = Listbox(selectmode=EXTENDED)

To query the selection, use curselection method. It returns a list of item indexes, but a bug in tkinter 1.160 (Python 2.2) and earlier versions causes this list to be returned as a list of strings, instead of integers. This may be fixed in later versions of tkinter, so you should make sure that your code is written to handle either case. Here’s one way to do that:

items = map(int, list.curselection())

In versions before Python 1.5, use string.atoi instead of int.

Use the get method to get the list item corresponding to a given index. Note that get accepts either strings or integers, so you don’t have to convert the indexes to integers if all you’re going to do is to pass them to get.

You can also use a listbox to represent arbitrary Python objects. In the next example, we assume that the input data is represented as a list of tuples, where the first item in each tuple is the string to display in the list. For example, you could display a dictionary by using the items method to get such a list.

self.lb.delete(0, END) # clear
for key, value in data:
    self.lb.insert(END, key)
self.data = data

When querying the list, simply fetch the items from the data attribute, using the selection as an index:

items = self.lb.curselection()
items = [self.data[int(item)] for item in items]

In earlier versions of Python, you can use this instead:

items = self.lb.curselection()
try:
    items = map(int, items)
except ValueError: pass
items = map(lambda i,d=self.data: d[i], items)

Unfortunately, the listbox doesn’t provide a command option allowing you to track changes to the selection. The standard solution is to bind a double-click event to the same callback as the OK (or Select, or whatever) button. This allows the user to either select an alternative as usual, and click OK to carry out the operation, or to select and carry out the operation in one go by double-clicking on an alternative. This solution works best in BROWSE and EXTENDED modes.

lb.bind("<Double-Button-1>", self.ok)

FIXME: show how to use bindtags to insert custom bindings after the standard bindings

FIXME: show how to use custom events in later versions of tkinter

If you wish to track arbitrary changes to the selection, you can either rebind the whole bunch of selection related events (see the Tk manual pages for a complete list of Listbox event bindings), or, much easier, poll the list using a timer:

class Dialog(Frame):

    def __init__(self, master):
        Frame.__init__(self, master)
        self.list = Listbox(self, selectmode=EXTENDED)
        self.list.pack(fill=BOTH, expand=1)
        self.current = None
        self.poll() # start polling the list

    def poll(self):
        now = self.list.curselection()
        if now != self.current:
            self.list_has_changed(now)
            self.current = now
        self.after(250, self.poll)

    def list_has_changed(self, selection):
        print "selection is", selection

By default, the selection is exported via the X selection mechanism (or the clipboard, on Windows). If you have more than one listbox on the screen, this really messes things up for the poor user. If she selects something in one listbox, and then selects something in another, the original selection disappears. It is usually a good idea to disable this mechanism in such cases. In the following example, three listboxes are used in the same dialog:

b1 = Listbox(exportselection=0)
for item in families:
    b1.insert(END, item)

b2 = Listbox(exportselection=0)
for item in fonts:
    b2.insert(END, item)

b3 = Listbox(exportselection=0)
for item in styles:
    b3.insert(END, item)

The listbox itself doesn’t include a scrollbar. Attaching a scrollbar is pretty straightforward. Simply set the xscrollcommand and yscrollcommand options of the listbox to the set method of the corresponding scrollbar, and the command options of the scrollbars to the corresponding xview and yview methods in the listbox. Also remember to pack the scrollbars before the listbox. In the following example, only a vertical scrollbar is used. For more examples, see pattern section in the Scrollbar description.

frame = Frame(master)
scrollbar = Scrollbar(frame, orient=VERTICAL)
listbox = Listbox(frame, yscrollcommand=scrollbar.set)
scrollbar.config(command=listbox.yview)
scrollbar.pack(side=RIGHT, fill=Y)
listbox.pack(side=LEFT, fill=BOTH, expand=1)

With some more trickery, you can use a single vertical scrollbar to scroll several lists in parallel. This assumes that all lists have the same number of items. Also note how the widgets are packed in the following example.

 
    def __init__(self, master):
        scrollbar = Scrollbar(master, orient=VERTICAL)
        self.b1 = Listbox(master, yscrollcommand=scrollbar.set)
        self.b2 = Listbox(master, yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.yview)
        scrollbar.pack(side=RIGHT, fill=Y)
        self.b1.pack(side=LEFT, fill=BOTH, expand=1)
        self.b2.pack(side=LEFT, fill=BOTH, expand=1)

    def yview(self, *args):
        apply(self.b1.yview, args)
        apply(self.b2.yview, args)

Reference #

Listbox(master=None, **options) (class) [#]

A scrolling listbox.

master
Parent widget.
**options
Widget options. See the description of the config method for a list of available options.

activate(index) [#]

Activates the given index (it will be marked with an underline). The active item can be refered to using the ACTIVE index.

index
Index specifier.

bbox(self, index) [#]

Gets the bounding box of the given item text.

index
Index specifier.
Returns:
The bounding box, as a 4-tuple (xoffset, yoffset, width, height). If the item is not visible, this method returns None. If the item is partially visible, the box may extend outside the visible area.

config(**options) [#]

Modifies one or more widget options. If no options are given, the method returns a dictionary containing all current option values.

**options
Widget options.
activestyle=
Default is underline. (the option database name is activeStyle, the class is ActiveStyle)
background=
Default value is ‘SystemButtonFace’. (background/Background)
bg=
Same as background.
borderwidth=
Default value is 2. (borderWidth/BorderWidth)
bd=
Same as borderwidth.
cursor=
No default value. (cursor/Cursor)
disabledforeground=
Default is system specific. (disabledForeground/DisabledForeground)
exportselection=
Default value is 1. (exportSelection/ExportSelection)
font=
Default value is system specific. (font/Font)
foreground=
Default value is system specific. (foreground/Foreground)
fg=
Same as foreground.
height=
Default value is 10. (height/Height)
highlightbackground=
Default value is system specific. (highlightBackground/HighlightBackground)
highlightcolor=
Default value is system specific. (highlightColor/HighlightColor)
highlightthickness=
Default value is 1. (highlightThickness/HighlightThickness)
listvariable=
No default value. (listVariable/Variable)
relief=
Default is SUNKEN. (relief/Relief)
selectbackground=
Default is system specific. (selectBackground/Foreground)
selectborderwidth=
Default is 1. (selectBorderWidth/BorderWidth)
selectforeground=
Default is system specific. (selectForeground/Background)
selectmode=
Default is BROWSE. (selectMode/SelectMode)
setgrid=
Default is 0. (setGrid/SetGrid)
state=
Default is NORMAL. (state/State)
takefocus=
No default value. (takeFocus/TakeFocus)
width=
Default is 20. (width/Width)
xscrollcommand=
No default value. (xScrollCommand/ScrollCommand)
yscrollcommand=
No default value. (yScrollCommand/ScrollCommand)

curselection() [#]

Gets a list of the currently selected alternatives. The list contains the indexes of the selected alternatives (beginning with 0 for the first alternative in the list).
In most Python versions, the list contains strings instead of integers. Since this may change in future versions, you should make sure your code can handle either case. See the patterns section for a suggested solution.

Returns:
A list of index specifiers.

delete(first, last=None) [#]

Deletes one or more items. Use delete(0, END) to delete all items in the list.

first
First item to delete.
last
Last item to delete. If omitted, a single item is deleted.

get(first, last=None) [#]

Gets one or more items from the list. This function returns the string corresponding to the given index (or the strings in the given index range). Use get(0, END) to get a list of all items in the list. Use get(ACTIVE) to get the active (underlined) item.

first
First item to return.
last
Last item to return. If omitted, a single item is returned.
Returns:
A list of strings.

index(index) [#]

Returns the numerical index (0 to size()-1) corresponding to the given index. This is typically ACTIVE, but can also be ANCHOR, or a string having the form “@x,y” where x and y are widget-relative pixel coordinates.

index
Index specifier.
Returns:
Numerical index.

insert(index, *elements) [#]

Inserts one or more items at given index (this works as for Python lists; index 0 is before the first item). Use END to append items to the list. Use ACTIVE to insert items before the the active (underlined) item.

index
Index specifier.
*elements
One or more elements to add.

itemcget(index, option) [#]

Gets a configuration option for an individual listbox item.

index
option

itemconfig(index, **options) [#]

Modifies the configuration for an individual listbox item.

index
**options

itemconfig(index, **options) [#]

Same as itemconfig.

nearest(y) [#]

Returns the index nearest to the given coordinate (a widget-relative pixel coordinate).

y
Coordinate.
Returns:
An index.

scan_dragto(x, y) [#]

Scrolls the widget contents according to the given mouse coordinate. The text is moved 10 times the distance between the scanning anchor and the new position.

x
Mouse coordinate.
y
Mouse coordinate.

scan_mark(x, y) [#]

Sets the scanning anchor for fast horizontal scrolling to the given mouse coordinate.

x
Mouse coordinate.
y
Mouse coordinate.

see(index) [#]

Makes sure the given list index is visible. You can use an integer index, or END.

index
Index specifier.

select_anchor(index) [#]

Same as selection_anchor.

select_clear(first, last=None) [#]

Same as selection_clear.

select_includes(index) [#]

Same as selection_includes.

select_set(first, last=None) [#]

Same as selection_set.

selection_anchor(index) [#]

Sets the selection anchor to the given index. The anchor can be refered to using the ANCHOR index.

index
Index specifier.

selection_clear(first, last=None) [#]

Removes one or more items from the selection.

first
First item to remove.
last
Last item to remove. If omitted, only one item is removed.

selection_includes(index) [#]

Checks if an item is selected.

index
Index specifier.
Returns:
A true value if the item is selected.

selection_set(first, last=None) [#]

Adds one or more items to the selection.

first
First item to add.
last
Last item to add. If omitted, only one item is added.

size() [#]

Returns the number of items in the list. The valid index range goes from 0 to size()-1.

Returns:
The number of items in this list.

xview(column, *extra) [#]

Controls horizontal scrolling.

If called without an arguement, this method determines which part of the full list that is visible in the horizontal direction. This is given as the offset and size of the visible part, given in relation to the full size of the list (1.0 is the full list).

If called with a single argument, this method adjusts the list so that the given character column is at the left edge of the listbox.

If called with the string “moveto” and a fraction, this method behaves like xview_moveto. If called with the string “scroll” and two more arguments, this method behaves like xview_scroll.

column
The column to place at the left edge, or a string specifying what subcommand to execute.
*extra
Additional arguments for the “moveto” and “scroll” forms. See above for details.
Returns:
If called without any arguments, a 2-tuple containing the left offset and the view size (relative to the full width).

xview_moveto(fraction) [#]

Adjusts the list so that the given offset is at the left (top) edge of the listbox. Offset 0.0 is the beginning of the list, 1.0 the end. These methods are used by the Scrollbar bindings when the user drags the scrollbar slider.

fraction
Offset.

xview_scroll(number, what) [#]

Scrolls the list view horizontally by the given amount.

number
Number of units.
what
What unit to use. This can be either “units” (characters) or “pages” (larger steps).

yview(*what) [#]

Controls vertical scrolling. This method works like xview, but controls vertical scrolling.

To make sure that a given item is visible, use the see method.

index
The index to place at the top edge, or a string specifying what subcommand to execute.
*extra
Additional arguments for the “moveto” and “scroll” forms.
Returns:
If called without any arguments, a 2-tuple containing the top offset and the view size (relative to the list size).

yview_moveto(fraction) [#]

Adjusts the list view so that the given offset is at the left edge of the canvas. Offset 0.0 is the beginning of the entry string, 1.0 the end.

fraction
Offset.

yview_scroll(number, what) [#]

Scrolls the list view vertically by the given amount.

number
Number of units.
what
What unit to use. This can be either “units” (characters) or “pages” (larger steps).

 

A Django site. rendered by a django application. hosted by webfaction.