Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting a callback when a Tkinter Listbox selection is changed?

There are a number of ways of getting callbacks when Text or Entry widgets are changed in Tkinter, but I haven't found one for Listbox's (it doesn't help that much of the event documentation I can find is old or incomplete). Is there some way of generating an event for this?

like image 470
bfops Avatar asked Jul 02 '11 02:07

bfops


3 Answers

def onselect(evt):     # Note here that Tkinter passes an event object to onselect()     w = evt.widget     index = int(w.curselection()[0])     value = w.get(index)     print 'You selected item %d: "%s"' % (index, value)  lb = Listbox(frame, name='lb') lb.bind('<<ListboxSelect>>', onselect) 
like image 147
Pierre-Jean Coudert Avatar answered Oct 01 '22 10:10

Pierre-Jean Coudert


You can bind to the <<ListboxSelect>> event. This event will be generated whenever the selection changes, whether it changes from a button click, via the keyboard, or any other method.

Here's a simple example which updates a label whenever you select something from the listbox:

import tkinter as tk  root = tk.Tk() label = tk.Label(root) listbox = tk.Listbox(root) label.pack(side="bottom", fill="x") listbox.pack(side="top", fill="both", expand=True)  listbox.insert("end", "one", "two", "three", "four", "five")  def callback(event):     selection = event.widget.curselection()     if selection:         index = selection[0]         data = event.widget.get(index)         label.configure(text=data)     else:         label.configure(text="")  listbox.bind("<<ListboxSelect>>", callback)  root.mainloop() 

screenshot

This event is mentioned in the canonical man page for listbox. All predefined virtual events can be found on the bind man page.

like image 20
Bryan Oakley Avatar answered Oct 01 '22 11:10

Bryan Oakley


I had the problem that I needed to get the last selected item in a listbox with selectmode=MULTIPLE. In case someone else has the same problem, here is what I did:

lastselectionList = []
def onselect(evt):
    # Note here that Tkinter passes an event object to onselect()
    global lastselectionList
    w = evt.widget
    if lastselectionList: #if not empty
    #compare last selectionlist with new list and extract the difference
        changedSelection = set(lastselectionList).symmetric_difference(set(w.curselection()))
        lastselectionList = w.curselection()
    else:
    #if empty, assign current selection
        lastselectionList = w.curselection()
        changedSelection = w.curselection()
    #changedSelection should always be a set with only one entry, therefore we can convert it to a lst and extract first entry
    index = int(list(changedSelection)[0])
    value = w.get(index)
    tkinter.messagebox.showinfo("You selected ", value)
listbox = tk.Listbox(frame,selectmode=tk.MULTIPLE)
listbox.bind('<<ListboxSelect>>', onselect)
listbox.pack()
like image 43
Alex Avatar answered Oct 01 '22 11:10

Alex