Why Is Button Parameter "Command" Executed When Declared

Why is Button parameter command executed when declared?

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.

Button parameter “command” executes when declared, but not when pressed

bind and command= expect "function name" - it means without () and arguments.

If you need to assign function with arguments then use lambda

Button(..., command=lambda:button_map_set(x, y))

or create function without arguments

def test():
button_map_set(x, y)

Button(..., command=test)

if you need run more functions when you press button then use function

def test():
button_map_set(x, y)
button_map()

Button(..., command=test)

-

The same is with bind but bind sends event so function has to receive this information

def test(event):
button_map_set(x, y)
button_map()

btn.bind("<Button-1>", test)

<Button-1> means left mouse click.

-

If you need use the same functions with bind and command= you can use default value None for event

def test(event=None):
button_map_set(x, y)
button_map()

Button(..., command=test) # run `test(None)`
btn.bind("<Button-2>", test) # run `test(event)`

<Button-2> means right mouse click.


BTW: own button with 3 colors

import tkinter as tk

class MyButton(tk.Button):

colors = ['red', 'blue', 'orange']

def __init__(self, *args, **kwargs):
tk.Button.__init__(self, *args, **kwargs)

# current color number
self.state = 0

# set color
self.config(bg=self.colors[self.state])

# assign own function to click button
self.config(command=self.change_color)

def change_color(self):
# change current color number
self.state = (self.state + 1) % len(self.colors)

# set color
self.config(bg=self.colors[self.state])

root = tk.Tk()

for __ in range(5):
MyButton(root, text="Hello World").pack()

root.mainloop()

You can add more colors to the list colors and it will work too.

Understanding function call for tkinter button command

When you run a function in Python (like but = Button(root, text="click here to do nothing",command=click())), first all of the arguments get evaluated and then passed to the function. So, you are calling click() and then assigning its return value to the command. If it returns None or something else that Button can handle you will get no error. When you pass just click, you actually tell the function that it is supposed to call that function whenever you click the button.

Some simple code to clarify the issue:

def foo(bar):
print("\tCalling function {} from foo".format(bar))
if bar:
bar()

def fun():
print("\tExecuting fun function")

print("\nPassing function")
foo(fun)

print("\nPassing function return value")
foo(fun())

If you check out the outputs you will notice that they get executed in different order - in the second case, fun is executed first, returns None and than that None value is given to foo as a bar argument.

Passing function
Calling function <function fun at 0x000001A79F8863A0> from foo
Executing fun function

Passing function return value
Executing fun function
Calling function None from foo

As to why there is no error - why would there be?
Both are valid statements. You could have a function that returns other function and pass it to the button that way.

Tkinter button command activates upon running program?

Make your event handler a lambda function, which calls your get_dir() with whatever arguments you want:

xbBrowse = Button(frameN, text="Browse...", font=fontReg, command=lambda : self.get_dir(xbPath))

Button command being called automatically

Read the section here on passing callbacks.

You are storing the result of that function to the command argument and not the function itself.

I believe this:

command = lambda: bot_analysis_frame(eventConditionL,eventBreakL)

might work for you.



Related Topics



Leave a reply



Submit