Re: Tkinter: passing parameters to menu commands

Discussion in 'Python' started by Philippe C. Martin, Jan 7, 2005.

  1. >>menu.add_cascade(label="File", menu=filemenu)
    >>filemenu.add_command(label="New", command=lambda: callback('New'))
    >>filemenu.add_command(label="Open...", command=lambda:

    callback('Open'))
    >>filemenu.add_separator()
    >>filemenu.add_command(label="Exit", command=lambda: callback('Exit'))

    mainloop()
    >>Of course you could do this with named forwarding functions if you

    prefer


    I'm not sure what 'named forwarding functions' 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'))





    Regards,

    Philippe




    --
    ***************************
    Philippe C. Martin
    SnakeCard LLC
    www.snakecard.com
    ***************************
     
    Philippe C. Martin, Jan 7, 2005
    #1
    1. Advertising

  2. Philippe C. Martin

    Kent Johnson Guest

    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
     
    Kent Johnson, Jan 8, 2005
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ben Pfaff

    Re: man pages for C commands (GCC commands)

    Ben Pfaff, Jun 24, 2003, in forum: C Programming
    Replies:
    4
    Views:
    3,975
    Thomas Stegen
    Jun 28, 2003
  2. Tim Stanka
    Replies:
    1
    Views:
    805
    Jeff Epler
    Aug 2, 2004
  3. Philippe C. Martin

    Tkinter: passing parameters to menu commands

    Philippe C. Martin, Jan 7, 2005, in forum: Python
    Replies:
    1
    Views:
    298
    Kent Johnson
    Jan 7, 2005
  4. Philippe C. Martin
    Replies:
    1
    Views:
    354
    Michael Fuhr
    Jan 7, 2005
  5. Ramon F Herrera
    Replies:
    8
    Views:
    483
    Pascal J. Bourguignon
    Sep 13, 2009
Loading...

Share This Page