Python Forum
[Tkinter] Button 'command' Argument Confusion - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: GUI (https://python-forum.io/forum-10.html)
+--- Thread: [Tkinter] Button 'command' Argument Confusion (/thread-35506.html)

Pages: 1 2


Button 'command' Argument Confusion - gw1500se - Nov-10-2021

I am confused by the 'command' argument for buttons. I have the following button defined:
submitButton=tk.Button(top,text='Submit',command=submitData(top)).grid(row=rw,column=2,pady=5,sticky=tk.W)
The command (submitData) is being executed immediately upon display before the button is clicked. The when I click the button, nothing is executed. What am I doing wrong? TIA


RE: Button 'command' Argument Confusion - Yoriz - Nov-10-2021

You are supposed to pass something callable to command, when the button is pressed it would then do the call,
You are actually passing something that is already being called the result of this call is being passed to the command.
Create a function/method that will do the actions you want to happen when a button is pressed, pass that uncalled function to command.


RE: Button 'command' Argument Confusion - deanhystad - Nov-10-2021

This code makes a button and returns a handle to the button.
submitButton=tk.Button(top,text='Submit',command=submitData(top))
This code tells the grid layout in the parent window (top) how it should layout the new button. .grid() returns None.
submitButton.grid(row=rw,column=2,pady=5,sticky=tk.W)
When you string the two commands together you get a new button in the right spot, but the value in submitButton is None, the return value of the .grid() calll.


RE: Button 'command' Argument Confusion - gw1500se - Nov-11-2021

Thanks for the replies but that is exactly what I am doing. The subroutine 'submitData' exists and is not called anywhere else (one and only one reference). That is the confusing part. How is it getting called if not from the button and even if it is, why does clicking the button not call it again?

As for what the button returns, I am not using that reference anywhere so it doesn't matter. Indeed I did even equate it to a variable.


RE: Button 'command' Argument Confusion - Yoriz - Nov-11-2021

submitData is being called with the argument top
submitData(top)
to have a button do the call you would have a function or method here is an example with a function

def call_me():
    print("I was Called")
command would be passed call_me without the () so when the button is clicked it would do the calling
command=call_me
not
command=call_me()

See the following link to another forum post for an example of using partial to send values to a function/method on a button click
https://python-forum.io/thread-28552-post-121468.html#pid121468


RE: Button 'command' Argument Confusion - gw1500se - Nov-11-2021

Thanks. Then how do I pass an argument to the command?

The bottom line is I want to process the entry widgets in 'top' when the button is clicked. That means I have to pass the parent to the subroutine to extract the data, right?


RE: Button 'command' Argument Confusion - Yoriz - Nov-11-2021

I already added a link of how to do that at the end of my previous post.


RE: Button 'command' Argument Confusion - gw1500se - Nov-11-2021

Sorry, I missed that. I was not aware of 'partial'. Some of this is hard to get from the documentation. Kind of like looking up how to spell a word in the dictionary. You have to know how to spell it before you can look it up. Thanks.


RE: Button 'command' Argument Confusion - deanhystad - Nov-11-2021

Your code does this:
tempValue = submitData(top)
tempButton = tk.Button(top,text='Submit',command=tempValue)
submitButton = tempButton.grid(row=rw,column=2,pady=5,sticky=tk.W)
This ends up setting submitButton=None and probably binds the button command=None.

To specify an argument in the command callback you can use a lambda expression or a partial function. This is your code fixed using a lambda expression.
submitButton = tk.Button(top, text='Submit', command=lambda: submitData(top))
submitButton.grid(row=rw, column=2, pady=5, sticky=tk.W)
The lambda expression creates a function that looks something like this:
def unnamed_function():
    submitData(top)
And binding command to the lambda expression does something like this:
submitButton = tk.Button(top, text='Submit', command=unnamed_function)
So command is bound to a function, not a function result, and the function you want to call is not called until the lambda expression is evaluated.


RE: Button 'command' Argument Confusion - gw1500se - Nov-11-2021

OK, so I can use lambda rather than partial to get to the same place. Thus I wouldn't need to include another library. Thanks.