0

I have a tkinter button, that when pressed should trigger creation of a custom class (class "manual_entry").

The custom class in its init() has creation of tkinter toplevel window. Snippet of code for clarify:

def __init__(self,main,myobject):
   manual=tk.Toplevel()
   something something

This toplevel windows does something to myobject, which is another class irrelevant to question.

When I call this class, for example:

variable=manual_entry(main,myobject)

it works perfectly. But what I specifically want is that this class be created upon a button prompt from tkinter main window. Snipped of code:

def create_ent(main,myobject):
    variable=manual_entry(main,myobject)

tk.Button(master=main,text="!",command=create_ent(main,museobj).grid()

Now what I should have is a tkinter window containing only button "!" which when I press, I get my own toplevel window. But instead, I simply get toplevel window ("manual") without even touching "!" button.

Upon further experimentation, if I were to do this

def test(a):
   print(a)
   return()
a="test"
tk.Button(master=main,text="!",command=beg(a)).grid()
main.mainloop()

What I get is automatically printed "test", without any prompt for button pressing.

What I want, in a nutshell, is a way to pass function that takes arguments as a tkinter command.

3
  • 1
    Use lambda: command=lambda: create_ent(main,museobj). Commented Mar 23, 2021 at 11:11
  • 2
    or look at this Commented Mar 23, 2021 at 11:11
  • @acw1668 that works and thanks, I'll implement that! But why does command need to be passed as lambda function? Commented Mar 23, 2021 at 11:28

1 Answer 1

2

For passing in arguments, you will have to use lambda or functools.partial. I recommend using lambda as there is no extra imports.

tk.Button(master=main,text="!",command=lambda: create_ent(main,museobj)).grid()
tk.Button(master=main,text="!",command=lambda: beg(a)).grid()

Or using partial would be like:

from functools import partial

tk.Button(master=main,text="!",command=partial(create_ent,main,museobj)).grid()
tk.Button(master=main,text="!",command=partial(beg,a)).grid()

Click here to read more about functools.partial


Why do we have to use these lambda or partial?

It is just because when you use () with a function, python calls the function directly and suddenly, which clearly defies the purpose of having a button. So you use lambda or partial which create another function that stores the given function or expression(in case of lambda) which will be called by tkinter only when the button is pressed.

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

3 Comments

Yeay finally someone recognised that functools.partial exists.
If you don't mind me asking, why exactly do functions need to be passed as lambda for passing in arguments?
@ivan199415 I've updated the answer with that question too.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.