Newbie (faq!): pmw/tkinter menubar command-option

Martin Rand hsl at tcp.co.uk
Sat Aug 5 02:45:05 EDT 2000


On Fri, 04 Aug 2000 14:57:18 +0200, Brian Elmegaard <be at et.dtu.dk>
wrote:

>Thanks for the answer.
>I am not sure, I understand fully what you mean. So, please let me ask
>again.
>
>> 
>> When you assign to the 'command' argument, you need to pass a
>> *reference* to a function; but what you are doing is passing the
>> result of *invoking* the function when you construct the menu. In this
>> example the function doesn't return a result, so 'command' gets
>> assigned 'None' in each case. (And so never tries to do anything for
>> the callback.)
>> 
>I think I get this.
>
>> Since in this artificial example (and some real-life ones) you may
>> want to pass a parameter to a common function, you can construct an
>> anonymous "wrapper" function to look after the specific parameter
>> generation, using a lambda expression. For instance:
>> 
>> filemenu.add_command(label="New", command=lambda: callback('new'))
>> 
>
>Ok, this works. What I want to make is a canvas, where I may put
>different figures on by invoking functions. This doesn't seem to work as
>you described, however.
>
>What I have is a class Demo, where the canvas and menu is created in
>__init__ and assignments as:
>        self.Canvas=Canvas
>        self.canvas=Canvas.component('canvas')
>are done.
>
>A menu is created with an entry like:
>        menuBar.addmenuitem('ComponentList','command',
>                            label='Round Thing',
>                            command=self.addComponent(150,30))
>
>where addComponent says:
>    def addComponent(self,x,y):
>	width = 10 
>	height = 10 
>	self.canvas.create_oval(
>	    x - width, y - height, x + width, y + height)
>
>It is defined inside the class. This puts a circle on the canvas during
>initialization, but probably for the same reason as explained above, it
>is assigned the same None, and must be changed. But, to what?

Yes,

                command=self.addComponent(150,30)

is invoking the addComponent function rather than passing a reference
to it. Once again, you can use a lambda expression - which in essence
defines a new function and provides an anonymous function reference to
it. But in this case you need to include an argument (well, a
one-element argument tuple) in the lambda, before the colon, to handle
'self'. It goes like this:

	command=lambda s=self: s.addComponent(150,30)


--
Martin Rand
Highfield Software Ltd
mwr at highfield-software.co.uk
Phone: +44 (0)23 8025 2445
Fax:   +44 (0)23 8025 2445



More information about the Python-list mailing list