When you use () with a function name(func(args)), then it is immediately calling/invoking the function while python is executing the line, you do not want that. You want to ONLY call the function when the button is clicked. tkinter will internally call the function for you, all you have to do is give the function name.
Why use lambda? Think of it as a function that returns another function, your code can be lengthened to:
func = lambda: comando_click("Nova_Mensagem")
botao = Button(menu_inicial, text = "Executar", command=func)
func is the function name and if you want to call it, you would say func(). And when you say command=comando_click("Nova_Mensagem") then command has the value returned by command click(because you call the function with ()), which is None and if I'm not wrong, if the given value is None, it will not be called by tkinter. Hence your function is executed just once because of () and as a result of calling the function, you are assigning the value of the function call(None) before the event loop starts processing the events.
Some other methods:
- Using
partialfromfunctools:
from functools import partial
botao = Button(.....,command=partial(comando_click,"Nova_Mensagem"))
- Using a helper function:
def helper(args):
def comando_click():
print(args)
return comando_click
botao = Button(...., command=helper("Nova_Mensagem"))
IMO, lambdas are the easiest way to proceed with calling a function with arguments.
Understanding Python Lambda behavior with Tkinter Button - Stack Overflow
python - Using the lambda function in 'command = ' from Tkinter. - Stack Overflow
What exactly is "lambda" in Python? - Stack Overflow
Tkinter: pass reference to self to lambda function?
Videos
When you use () with a function name(func(args)), then it is immediately calling/invoking the function while python is executing the line, you do not want that. You want to ONLY call the function when the button is clicked. tkinter will internally call the function for you, all you have to do is give the function name.
Why use lambda? Think of it as a function that returns another function, your code can be lengthened to:
func = lambda: comando_click("Nova_Mensagem")
botao = Button(menu_inicial, text = "Executar", command=func)
func is the function name and if you want to call it, you would say func(). And when you say command=comando_click("Nova_Mensagem") then command has the value returned by command click(because you call the function with ()), which is None and if I'm not wrong, if the given value is None, it will not be called by tkinter. Hence your function is executed just once because of () and as a result of calling the function, you are assigning the value of the function call(None) before the event loop starts processing the events.
Some other methods:
- Using
partialfromfunctools:
from functools import partial
botao = Button(.....,command=partial(comando_click,"Nova_Mensagem"))
- Using a helper function:
def helper(args):
def comando_click():
print(args)
return comando_click
botao = Button(...., command=helper("Nova_Mensagem"))
IMO, lambdas are the easiest way to proceed with calling a function with arguments.
In this code:
command=comando_click("Nova_Mensagem")
you have called the comando_click function, once, and assigned the result (None) to the command argument. Nothing will happen when command is called (in fact you should get a TypeError exception because None is not callable).
In this code:
command=lambda:comando_click("Nova_Mensagem")
you have not actually called comando_click yet -- you have created a new function (using lambda) that will in turn call comando_click when it is called. Every time the button is clicked, your new function will get called.
If the lambda is confusing, you can do the exact same thing with a def like this:
def button_command():
comando_click("Nova_Mensagem")
...
command=button_command # no ()! we don't want to actually call it yet!
The lambda expression is just an alternative to using def when you want to create a small single-use function that doesn't need a name (e.g. you want to make a function that calls another function with a specific argument, exactly as you're doing here).
The command lambda does not take any arguments at all; furthermore there is no evt that you can catch. A lambda can refer to variables outside it; this is called a closure. Thus your button code should be:
bouton1 = Button(main_window, text="Enter",
command = lambda: get(Current_Weight, entree1))
And your get should say:
def get(loot, entree):
loot = float(entree.get())
print(loot)
Actually, you just need the Entry object entree1 as the lamda pass-in argument. Either statement below would work.
bouton1 = Button(main_window, text="Enter", command=lambda x = entree1: get(x))
bouton1 = Button(main_window, text="Enter", command=lambda : get(entree1))
with the function get defined as
def get(entree):
print(float(entree.get()))
Lambda is more of a concept or programming technique then anything else.
Basically it's the idea that you get a function (a first-class object in python) returned as a result of another function instead of an object or primitive type. I know, it's confusing.
See this example from the python documentation:
def make_incrementor(n):
return lambda x: x + n
f = make_incrementor(42)
f(0)
>>> 42
f(1)
>>> 43
So make_incrementor creates a function that uses n in it's results. You could have a function that would increment a parameter by 2 like so:
f2 = make_incrementor(2)
f2(3)
>>> 5
This is a very powerful idea in functional programming and functional programming languages like lisp & scheme.
Hope this helps.
Lambdas are not anonymous functions. Lambdas are anonymous expressions.
They're accessed like functions, but they're not the same thing. Functions allow complex tasks: flow control, variable declarations and lists of statements containing expressions. Expressions are merely one part of a function, and that's what lambdas give you. They're severely limited compared to functions.
Python does not support anonymous functions. For examples of languages that do, see Javascript and Lua.
(Note: It's correct to call lambdas anonymous functions in functional languages, where the mathematical definition of "function" is used, but in procedural languages the word has a very different meaning than in mathematics.)
Early days on Tkinter for me and I'm struggling with something.
I have several buttons that I want to all call the same function when clicked but then determine what task to perform within that function based on which of the buttons was actually clicked.
One way I managed it was to pass a string to the lambda function e.g.
button.command=lambda clickFunction('red')
then:
def clickFunction(buttonColor):
etc.
but is there a way I can pass 'self' in the lambda function so that I could do it a different way e.g.
button.color = 'red'
button.command=lamda clickFunction(self)
then:
def clickFunction(self):
print("Button colour is " + self.color
this doesn't work but it can be sort of made to work by passing the button itself:
button.command=lambda clickFunction(button)
but I don't necessarily want to do that and am curious if there's a way to pass 'self' to the function instead as that strikes me as more flexible (especially as I'm trying to write a class to create buttons by passing a set of parameters to the button constructor so that when I have many buttons to create I don't have to type the same button construction code out multiple times. Forgive me if this approach is wrong too! ๐คฃ
I think I've read several hundred articles and Stackoverflow posts now but I can't seem to find the answer.