[Tutor] passing data to Python callback

Abel Daniel abli@freemail.hu
Sat Feb 22 02:25:02 2003


 vicki@stanfield.net (vicki@stanfield.net) wrote:
> How do you pass data to a callback? Is it done in the
> bind statement? I have done this in Motif, but I am new
> to this Python/Tkinter thing.
Get http://www.nmt.edu/tcc/help/lang/python/tkinter.ps, which
is the best reference doc I saw about tkinter. (There is a link to a pdf
version from http://www.nmt.edu/tcc/help/lang/python/tkinter.html, look
for 'Tkinter reference: a GUI for Python' in the local links section.)

On page 83 of that the 'extra arguments trick' is described which uses
lambdas to pass in extra arguments to the callbacks.
> 
> Here is a code snippet:
> 
> ---------------
> CommandListbox = Listbox(Frame1) 
> CommandListbox.insert("end","First entry")
> CommandListbox.insert("end","Second entry")
> CommandListbox.pack()
> index = CommandListbox.index('active')
> CommandListbox.bind('<Button-1>',
> CommandListboxCallback)
> ---------------
> 
> What I would like to do is pass the index of the
> selected entry to the callback, so how do I pass
> additional information beyond the event?
However, in this case, _you_ dont pass in the index, because you simply
don't know at the time you bind the callback. The callback function will
get one argument (the event object) when the event happens. This event
has a widget attribute, which is the widget where the event happened, in
this case the listbox. So the callback has to ask the listbox which
lines are selected. So it should look like this:

def callback(event):
    print 'selected lines:'
    print event.widget.curselection()

.curselection will return a tuple containing the indices of the selected
lines.
However, this naive binding won't work, the callback will print all sorts
of numbers, but not the ones which are currently selected. Further
inspection will show, that it prints the indices of the previous
selection. Why? You are binding to <Button-1> event, and that gets
called when the mouse button is pressed. At that moment, the listbox
itself didn't yet register the selection you made. So you should bind to
<ButtonRelease-1>, and it will work.

abli