2

I understand lambda functions quite well. Having said that, I have a Python tkinter GUI that opens a separate 'options' window - user enters text, then can click the "set" button, or press enter which is bound to the same button, to set the text and return to the main window.

It seems that the binding code for the enter key needs me to tell the lambda function I'm passing input (as I understand that's how they work and that's what I expect).

However - the 'command=' code for the button only works if I don't include it, which I don't understand.

Here is the code - my question is - how come in the button case I don't tell the lambda function I'm passing a variable into the function, but in the enter-key binding I do?

    saveBtn = tk.Button(saveWindow,text='Save', width=10,**command=lambda: pressed(fName)**)
    saveBtn.grid(row=2,column=2)        
    saveWindow.bind('<Return>',**lambda x: pressed(fName)**)
Stu
  • 17
  • 2
  • When tkinter calls your `command`, you already know what that the user pressed the button. But if you bind to something like: `""`, you might want to know which key was pressed so when `tkinter` calls your function it calls it with an `event` argument. Try printing it out to see it for your self – TheLizzard Jun 10 '21 at 11:21
  • authors of tkinter decided that button will run `function()` without any arguments. And they decided that `bind` will run `function(event)` with extra information. In other GUI frameworks - like `PyQt`, `PYGTK` - it may works different way and button may also send some extra information to function. – furas Jun 10 '21 at 12:35
  • @furas: _"authors of tkinter decided that button will run function() without any arguments."_ isn't exactly true. The binding requires a _callable_, and the rules of python don't let you designate a callable unless you use something like `lambda` or `functools.partial`. It's not really a tkinter thing, it's a python thing. – Bryan Oakley Jun 10 '21 at 13:54
  • @BryanOakley I wasn't thinking how to create callable but I was thinking how `mainloop` will execute assigned function - and this is authors of tkinter (or `tcl/tk`) decision that `mainloop` for `command=` will run this function without arguments but `bind` with run with `event` . – furas Jun 10 '21 at 14:16

1 Answers1

1

It seems that the binding code for the enter key needs me to tell the lambda function I'm passing input (as I understand that's how they work and that's what I expect).

Not quite. The bind command requires that you pass it a callable, and that callable must accept a single positional argument to receive the event object. The bind command doesn't care if the callable is a function, a lambda, or anything else. It simply must be callable and accept one argument.

If you need to pass in other arguments, you need to define a callable that takes care of the argument handling. The most common ways to do that are with lambda or functools.partial which let you create a new anonymous callable function.

... how come in the button case I don't tell the lambda function I'm passing a variable into the function, but in the enter-key binding I do?

The short answer is simply "that's how they are defined to work". The button's command will be called without any arguments, and a function called by bind will be passed an argument representing the event.

I suppose the reason for this is that normally a button's command doesn't need the event argument, since the event is largely irrelevant. Bound functions, on the other hand, quite often need the event argument.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685