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