4

I have been looking around for a long time for answers to this question but still hasn't find anything. I am creating a GUI using Tkinter, and I have two buttons that do mostly the same thing except they receive information from different widgets. One button is for an Entry widget and the other is for a Listbox widget. The callback function for these two buttons is long (about 200 lines), so I don't want to have separate functions for each button. I have if-statements in the beginning of this callback function to check which button is clicked, and then the codes will take the corresponding value. But I am not sure if the following code shows the right way to do this because apparently it doesn't work perfectly in my program. The callback function would only work for the first time, and if I click the other button I will receive an error. Here is a sample code that I created to illustrate the idea. Note that I want to check if the button is clicked, I do not want to check if the 'value' exists. Please help.

from Tkinter import *

root = Tk()

def DoSomething():
    # is this the right way to check which button is clicked?
    if button1:
        value = user_input.get()
    elif button2:
        value = choice.get(choice.curselection()[0])

    # then more codes that take 'value' as input.


button1 = Button(master,text='Search',command=DoSomething)
button1.pack()
button2 = Button(master,text='Search',command=DoSomething)
button2.pack()

user_input = Entry(master)
user_input.pack()
choice = Listbox(master,selectmode=SINGLE)
choice.pack()
#assume there are items in the listbox, I skipped this portion

root.mainloop()
4

1 回答 1

6

If you want to pass the actual widget into the callback, you can do it like this:

button1 = Button(master, text='Search')
button1.configure(command=lambda widget=button1: DoSomething(widget))
button2 = Button(master, text='Search')
button2.configure(command=lambda widget=button2: DoSomething(widget))

Another choice is to simply pass in a literal string if you don't really need a reference to the widget:

button1 = Button(..., command=lambda widget="button1": DoSomething(widget))
button2 = Button(..., command=lambda widget="button2": DoSomething(widget))

Another choice is to give each button a unique callback, and have that callback do only the thing that is unique to that button:

button1 = Button(..., command=ButtonOneCallback)
button2 = Button(..., command=ButtonTwoCallback)

def ButtonOneCallback():
    value = user_input.get()
    DoSomething(value)

def ButtonTwoCallback():
    value=choice.get(choice.curselection()[0])
    DoSomething(value)

def DoSomething(value):
    ...

There are other ways to solve the same problem, but hopefully this will give you the general idea of how to pass values to a button callback, or how you can avoid needing to do that in the first place.

于 2013-04-19T22:19:41.667 回答