[Edu-sig] Python Help - Thanks [callbacks]
Danny Yoo
dyoo@hkn.eecs.berkeley.edu
Tue, 20 May 2003 09:25:14 -0700 (PDT)
On Tue, 20 May 2003, Randy Latimer wrote:
> Here's the problem:
> She's defining a a DrawCircle function in class easel (the drawing
> canvas)
> The button for "Circle" is defined in the "panel" - tool bar.
> She's trying to call the DrawCircle function when she left clicks
> on the Circle button.
> But nothing happens now when the Circel button is pressed.
Hi Randy,
A valuable part of programming is knowing what to investigate when a
program fails. Since nothing's happening when the circle button is
pressed, we may want to look at the particular code that binds the button
to the DrawCircle function: there might be something there that we need to
look at.
The binding code is defined in the MakeGUI() method of the panel:
###
def MakeGUI(self,MyEasel,MyCanvas):
Circle = Button (self,text = "Circle")
Circle.pack(side = TOP,fill = X, anchor = N)
Circle.bind('<Button-1>', self.circle(self, MyEasel, MyCanvas))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
###
Ah! This bit of code looks suspicious. There are a few things wacky with
it The expression,
self.circle(self, MyEasel, MyCanvas)
calls the method circle() --- but isn't it a bit premature to call it now,
during the MakeGUI initialization?
Also, 'self' is already an implicit first argument in a method call, so
the first argument to this call looks redundant. Looking at the
self.circle definition, I'm assuming that you meant to send over the event
object?
Side note: it seems a little silly to pass MyEasel and MyCanvas around
everywhere; wouldn't it be better to make them attributes of our object?
Sorry, I'm getting backtracked. *grin* The problem appears to be a
confusion on how callbacks work. The code desires to bind <Button-1> to a
function that, when called, will itself call self.circle():
###
def bringUpCircle(event):
self.circle(MyEasel, MyCanvas)
###
And since it's perfectly ok to define internal functions in a method, we
can fix the binding bug by doing something like this:
###
def MakeGUI(self,MyEasel,MyCanvas):
Circle = Button (self,text = "Circle")
Circle.pack(side = TOP,fill = X, anchor = N)
def bringUpCircle(event):
self.circle(event, MyEasel, MyCanvas)
Circle.bind('<Button-1>', bringUpCircle)
###
For more information, see:
http://www.pythonware.com/library/tkinter/introduction/events-and-bindings.htm
Good luck to you!