[Tkinter-discuss] Re: Storing structured, 'widget-specific-data', then loading it back in la ter

stewart at midtoad.homelinux.org stewart at midtoad.homelinux.org
Tue Oct 5 17:50:50 CEST 2004


Quoting Chris Nethery <clnethery at juno.com>:

> 3) Lambda.  This may be more of a 'How does Lambda work?' question than
> anything, but here goes... ...With Button(..., command=lambda:
> self.getStoredData(self.widget)), am I creating another local function within
> the Button-widget method-call?  And, why do I need to do this, rather than
> call a variable assigned to the function call?

Chris, I've found that the use of lambda is a solution when you want to pass an
argument to a callback function.  If you simply create a command callback and
include an argument in its construction, that callback function gets executed as
soon as the GUI is drawn, which is not what we want!

so, you can create a button like so (inside some Class that creates the GUI):
b= Button(root, command = self.dosomething)) 
and will run properly, but you can't do the following:
b= Button(root, command = self.dosomething(arg))
Instead, you'd need to do this:
b= Button(root, command = lambda self=self, arg=arg: self.dosomething(arg))

Cameron Laird pointed out last week that you can also define an intermediate
function to pass the argument to instead of using a lambda function. 

Here's a little app (uses Pmw) that demonstrates three different ways of passing
arguments from a callback command:

----
title = 'Argument passing demonstration'

# Import Pmw from this directory tree.
import sys, time, string
sys.path[:0] = ['../../..']

import Tkinter
import tkFont
from tkMessageBox import *
import Pmw

class Demo:

    def anotherFunction(self):
        self.printMe(self.arg)
            

    def __init__(self, parent):
        
        # Create and pack the MenuBar.
        menuBar = Pmw.MenuBar(parent,
            hull_relief = 'raised',
            hull_borderwidth = 1)
        menuBar.pack(fill = 'x')
        self.menuBar = menuBar

        # Add some buttons to the MenuBar.
        menuBar.addmenu('File', 'Close this window or exit')
        menuBar.addmenuitem('File', 'command', 'Pass arg to new object',
            command = PrintOne("I'm a new object"),
            label = 'Pass arg to new object')
        menuBar.addmenuitem('File', 'command', 'Pass arg through lambda',
            command = lambda self=self, arg="I'm a lambda": printMe(self, arg),
            label = 'Pass arg through lambda')
        self.arg="I'm an intermediate"
        
        menuBar.addmenuitem('File', 'command', 'Pass through intermediate function',
            command = self.anotherFunction,
            label = 'Pass arg through intermediate function')

        menuBar.addmenuitem('File', 'separator')
        menuBar.addmenuitem('File', 'command', 'Exit the application',
            command = root.destroy,
            label = 'Exit')

        # Create and pack the main part of the window.
        self.mainPart = Tkinter.Label(parent,
            text = 'This is the\nmain part of\nthe window',
            padx = 30,
            pady = 30)
        self.mainPart.pack(fill = 'both', expand = 1)
            
    def printMe(self, arg):
        print(arg)
            
class PrintOne:
    def __init__(self, text):
        self.text = text

    def __call__(self):
        '''this method will be automatically called when an instance of the
PrintOne object is created'''
        print self.text

######################################################################

# Create demo in root window for testing.
if __name__ == '__main__':
    root = Tkinter.Tk()
    Pmw.initialise(root)
    root.title(title)

    widget = Demo(root)
    exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy)
    exitButton.pack(side = 'bottom')
    root.mainloop()




More information about the Tkinter-discuss mailing list