Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Tkinter: processing button clicks using lambda / eval

The following is the simplest code required to illustrate my question:

def function_one():
    pass
def function_two():
    pass

def button_clicked(function_name_as_string):
    # do stuff common to all button clicks
    # here...
    # then respond to specific button click by converting the
    # supplied function name string into an actual function which runs.
    eval(function_name_as_string + "()") 

button_one = Button(root,text="Run Function One",
                    command=lambda: button_clicked("function_one"))

button_two = Button(root,text="Run Function Two",
                    command=lambda: button_clicked("function_two"))

This is an attempt to make my tkinter code as compact as possible. Here, there are multiple buttons. But rather than write a function to handle each button click, I wanted a single function to handle all button clicks. In particular, that’s because there are some operations I want to execute in response to any button click, before responding to the specific button click. At the same time, I wanted to eliminate any lengthy if/elif statement in the button_clicked function, which would be required for the function to know which button had been clicked, and take appropriate action.

In my solution above, when a button is clicked, the command keyword calls my button_clicked function, but also uses lambda to send the name of the function I want to run in response to the button click. The button_clicked function executes the code common to all button clicks, then uses eval to convert the supplied function name (passed as a string) into an actual function that now runs.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

So the button_clicked function is not aware of which button was clicked. Rather, it is aware of what function ought to run in response to the specific button click. And this code runs perfectly.

I have never used lambda before, nor have I used eval. I came across both during a long search. But because both are new to me, I am a bit wary. My question is simply this: is the above approach correct and sound? Or are there hidden pitfalls that I may not be aware of? Thanks in advance.

>Solution :

I would argue it’s better to pass the actual function than the function name as a string. eval rarely adds any value over other solutions, and mostly just makes the code harder to understand.

def function_one():
    pass
def function_two():
    pass

def button_clicked(function):
    # do stuff common to all button clicks
    # here...
    # then respond to specific button click by calling 
    # the specified function
    function()

button_one = Button(root,text="Run Function One",
                    command=lambda: button_clicked(function_one))

button_two = Button(root,text="Run Function Two",
                    command=lambda: button_clicked(function_two))
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading