Philippe C. Martin wrote:
menu.add_cascade(label="File", menu=filemenu)
filemenu.add_command(label="New", command=lambda: callback('New'))
filemenu.add_command(label="Open...", command=lambda:

Of course you could do this with named forwarding functions if you

prefer


I'm not sure what 'named forwarding functions'

Bad choice of terminology, I just mean you can explicitly define def handleNew: callback('New')

etc.

are but I'm actually in a
class and when applying your suggestion in the following manner,
everything works (THANKS!)

****************************
def __Dec(self,p_string):
  for i in p_string:
    self.__Insert(i)
.
.
.
#menu creation
l_dec.add_command(label = 'ATR', command=lambda: self.__Dec('ATR'))
l_dec.add_command(label = 'IN', command=lambda:self.__Dec('IN'))
.
.
.
****************************

Yet I have a question:

If I replace the menu creation code as below, and since __Insert appends
the string p_string into a text widget that is created _after_ the menu
creation; the method __Dec seems to be called at the menu creation and
I get an error in __Insert because the test widget is equal to None.

My reflexes of C programmer tell me that command=self.__Dec.... just
passes a method pointer (sorry I said it) to add_command - yet it does
not seem to be so.
>
> What is actually going on ?
>
>
> #menu creation
> l_dec.add_command(label = 'ATR', command=self.__Dec('ATR'))
> l_dec.add_command(label = 'IN', command=self.__Dec('IN'))

self.__Dec is a reference to the function. It is similar to a method pointer so you don't need to apologize ;) The name of a function without the () is a reference. When you append () it becomes a call to the referenced function.

The command parameter for the menu must be a reference to a function. The function is called with no arguments when the menu is invoked.

So, you need a function of no arguments to handle the command. For example,

def handleMenu():
  print 'Handled'

filemenu.add_command(label="New", command=handleMenu)

Note there is no () after handleMenu. 'command' is bound to the function object; the function is not called until later.

OK, now suppose you want to pass a parameter to handleMenu?

def handleMenu(menuName):
  print 'Handled', menuName

Now what do you put in the command parameter? This won't work because you are *calling* handleMenu and assigning the result of the call (in this case the value None) to 'command':

filemenu.add_command(label="New", command=handleMenu('New')) # WRONG

You need a new function of zero arguments to bind to 'command'. Here is one way 
to do it:

def handleNew():
  handleMenu('New')

filemenu.add_command(label="New", command=handleNew) # OK

Note, again, no () after handleNew. 'command' is bound to the function object 
again.


OK, what about lambda? lambda is a way to create a simple anonymous function. One simple use of lambda is to make a new function that binds a parameter to another function.


lambda: handleMenu('New')

defines a function that does the same thing as handleNew. The value of the lambda expression is the function object. So

filemenu.add_command(label="New", command=lambda: handleMenu('New')) # OK

is another way to get the result you want.

Kent
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to