16

I'm new to Python and trying to write a program with tkinter. Why is the Hello-function below executed? As I understand it, the callback would only be executed when the button is pressed? I am very confused...

>>> def Hello():
        print("Hi there!")

>>> hi=Button(frame,text="Hello",command=Hello())
Hi there!
>>> 
0

2 Answers 2

40

It is called while the parameters for Button are being assigned:

command=Hello()

If you want to pass the function (not it's returned value) you should instead:

command=Hello

in general function_name is a function object, function_name() is whatever the function returns. See if this helps further:

>>> def func():
...     return 'hello'
... 
>>> type(func)
<type 'function'>
>>> type(func())
<type 'str'>

If you want to pass arguments, you can use a lambda expression to construct a parameterless callable.

>>> hi=Button(frame, text="Hello", command=lambda: Goodnight("Moon"))

Simply put, because Goodnight("Moon") is in a lambda, it won't execute right away, instead waiting until the button is clicked.

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you! Obvious follow-up is; how do I pass arguments? I am now reading about Lambda, it seems that might just be the answer.
@wjakobw - Pass argument to the function or pass the function as argument? In the first case you declare arguments in the function definition ex: def func(par1, par2): in the latter, you simply use the function name without parenthesis, as I outlined in my answer. Since you are admittedly new to python, may I suggest this reading? It's easy to follow and very enjoyable.
I would want to pass a variable as argument when the button is pressed. The usual way command=Hello(arg) won't work as the callback then contains parantheses and uses the return-value instead of the function. *In above example Hello-function takes no arguments, but imagine some other case.
@wjakobw - One of the regular patterns used in python is to pass a list of objects in which the first is the function, and the others its parameters (see the way subprocesses are called in the subprocess module, for example). If this is not an option, what you probably want is using closures. A nice article about their implementation in python is this one.
2

You can also use a lambda expression as the command argument:

import tkinter as tk
def hello():
    print("Hi there!")

main = tk.Tk()
hi = tk.Button(main,text="Hello",command=lambda: hello()).pack()
main.mainloop()

1 Comment

Lambda is completely unnecessary if you aren't passing arguments. You could improve your answer by showing how to use lambda to pass arguments.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.