0

I have an application that has a entry field and a button:

    from subprocess import *
    from Tkinter import *


    def remoteFunc(hostname):
            command = 'mstsc -v {}'.format(hostname)
            runCommand = call(command, shell = True)
            return

    app = Tk()
    app.title('My App')
    app.geometry('200x50+200+50')

    remoteEntry = Entry(app)
    remoteEntry.grid()

    remoteCommand = lambda x: remoteFunc(remoteEntry.get()) #First Option
    remoteCommand = lambda: remoteFunc(remoteEntry.get()) #Second Option

    remoteButton = Button(app, text = 'Remote', command = remoteCommand)
    remoteButton.grid()

    app.bind('<Return>', remoteCommand)

    app.mainloop()

and I want that when I insert an ip/computer name to the entry field it will sent it as a parameter to the command of the button, so when I press Return or pressing the button it will remote the computer with that name/ip.

When i execute this code with the first option (look at the code) it works only I press the Return key, and if I press the button this is the error:

Exception in Tkinter callback
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py", line 1532, in __call__
return self.func(*args)
TypeError: <lambda>() takes exactly 1 argument (0 given)

If I try the second option of remoteCommand only if I try to press the button It work but I if press the Return key i get this error:

Exception in Tkinter callback
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py", line 1532, in __call__
return self.func(*args)
TypeError: <lambda>() takes no arguments (1 given)

The only difference between the two is if lambda gets an argument or not.

2 Answers 2

1

The best solution in my opinion is to not use lambda. IMO, lambda should be avoided unless it really is the best solution to a problem, such as when a closure needs to be created.

Since you want the same function to be called from a binding on the return key, and from the click of a button, write a function that optionally accepts an event, and then simply ignores it:

For example:

def runRemoteFunc(event=None):
    hostname = remoteEntry.get()
    remoteFunc(hostname)
...
remoteButton = Button(..., command = remoteFunc)
...
app.bind('<Return>', remoteCommand)
Sign up to request clarification or add additional context in comments.

2 Comments

Little question: Why do you consider it better to avoid lambda? Because, I use it quite a lot, with tkinter widgets especially, which is a habbit I would change if I knew what is problematic about it.
@WillemvanHouten: I avoid lambda because it's just unnecessary extra syntax in many cases. Why use a function to call a function instead of just directly calling a function? lambda is useful when you need to pass arguments, but in my experience that's the exception rather than the rule.
1

Commands do not get arguments. Event handlers get an event as an argument. To have a function serve as both, use a default argument.

def remote(event=None):
     remoteFunc(remoteEntry.get())

Comments

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.