help: menu item callback in TK

Randall Hopper aa8vb at yahoo.com
Tue Feb 29 09:15:14 EST 2000


Lin Li:
 |Steve Holden wrote:
 |> lin li wrote:
 |> > I generated a menu using the data in a dynamically composed list.
 |> > Since I do not know what will be in the list, I can only have all the
 |> > command items in the menu to point to the same callback. Now
 |> > from inside the callback, how can I find out which menu item is
 |> > selected? ... I am running Python 1.5.2 with Tkinter on NT.
 |
 |Provided, of course, that I know how to use lambda. I decided to call this
 |an incentive and start learning.

------------------------------------------------------------------------------
A lambda is one way:

   callback = lambda option="Bananas": sys.stdout.write( option )

------------------------------------------------------------------------------
A function is a slightly better one.  You can use statements within it:

   def cb( option="Bananas" ):
      print option
   callback = cb

------------------------------------------------------------------------------
A callable object is yet another:

   class Call:
     def __init__( self, option ):
       self.option = option
     def __call__( self ):
       print self.option
   callback = Call( "Bananas" )

------------------------------------------------------------------------------
My personal favorite for Tkinter callbacks is a generalization on this last
one (thanks to Thomas Heller).  It allows you to write your callback
functions like normal, and then just use a generic callable object instance
as the "glue" to keep track of the callback registration arguments and pass
them to your callback.

   class Call:
     """Instances of this class store a function as well as a list of 
        arguments.  When they are called, the function will be called together
        with the arguments used for creating the instance.
        Slightly different than lambda, but nicer syntax."""
     def __init__ (self, func, *args):
       self.func = func           # save the function (or bound method, or ...)
       self.args = args           # save the arguments to use 
     def __call__ (self):
       apply (self.func, self.args) # call function, using args as arguments.

Put Call somewhere, then use it over and over, like this:

>>> def MyCallback( option ):
...   print option
... 
>>> callback = Call( MyCallback, "Bananas" )
>>> callback()
Bananas

In Tkinter:

>>> menu.add_checkbutton( label=item, command=Call( MyCallback, "Bananas" ) )

------------------------------------------------------------------------------
Also note that, for check and radio button options in specific, you can use
Tk string and int variables, respectively, to communicate the value so your
callback doesn't need arguments:

    self.check_val = StringVar()
    ...
    menu.add_checkbutton( label=item, variable=self.check_val,
                          command=self.CheckCB )
    ...
    def CheckCB( self ): print "variable is ", self.check_val.get()


-- 
Randall Hopper
aa8vb at yahoo.com




More information about the Python-list mailing list