Tkinter button and entry

443 views Asked by At

I have a couple of defined functions that I want to create buttons for in my GUI. A couple of these functions require one or two arguments(numbers) and that is what's causing problems for me. I have thought about a combination between a button and an entry where when I click the specific button(for one of my functions), an entry will pop up where I type in a number. Then when I press enter I want this number to be used as the argument for the function I have binded to my button and then the function should be executed.

1 function I want to bind to a button:

def move(power, tacho_units):
    MOTOR_CONTROL.cmd(5, power, tacho_units, speedreg=0, smoothstart=1, brake=0)
    is_ready(5)

We are working with Lego Mindstorms, so Im pretty sure that for example the function above could be a bit confusing for some people.

from Tkinter import *

class App:

    def __init__(self, master):

        frame = Frame(master)
        frame.pack()

        self.button = Button(frame, text="Move", command=!_______!)
        self.button.pack(side=LEFT)

root = Tk()

app = App(root)

root.mainloop()

root.destroy()

Does someone have any suggestions/solutions for me? I would appreciate if someone could help me. Do I create a function(that will open a new window with an entry) that I call when I click the Move button? The numbers(power and tacho_units in this function) that I type into the entry is what I want to be used for the function Move when I press enter.

2

There are 2 answers

0
furas On

Use lambda function to assign function with arguments

some_power = ... # set value
some_tacho_units = ... # set value

self.button = Button(frame, text="Move", command=lambda a=some_power,b=some_tacho_units:move(a, b) )

or

self.button = Button(frame, text="Move", command=lambda:move(5, 10))
3
Bryan Oakley On

Typically, the way to pass arguments to a function associated with a widget is to use lambda or functools.partial (note: these aren't the only ways). Both of these are somewhat advanced topics, but if you just follow an example, it's fairly safe to use them without fully understanding them.

Here's an example using lambda:

b = tk.Button(..., command=lambda power=1, tacho_units="x": move(power, tacho_units)

While not technically correct, just think of a lambda as a "def" but without a name. It takes arguments and can call functions.

Here is the same thing, using functools.partial:

b = tk.Button(..., command=functools.partial(move, power=1, tacho_units="x"))

Note: you'll have to add an import statement for functools.

functools.partial in essence copies the function (in this case, move) and provides default values for the arguments. Thus, when you call it with no arguments (as tkinter does by default), the parameters will have these default values.

HOWEVER...

Often it's easier to write a function to call your function. The purpose of this extra function is to gather the inputs -- presumably from other widgets -- and then call the final function. For example:

def do_move():
    power = power_input.get()
    tacho_units = tacho_input.get()
    move(power, tacho_units)

b = tk.Button(..., command=do_move)

Whether you use this third method depends on where the argument values come from. If you know the values at the time you create the widget, using lambda or functools.partial works because you can embed the arguments right there. If you're going to be getting the parameters from other widgets, the third form is preferable.