Basic methods & GUI assistance
The common way to do it is to define a short callback wrapper function with default arguments, which in turns calls the real event handler function with the arguments it needs. Here's an example based on your code:
import Tkinter as tkNUM_BUTTONS = 3button_list = []label_list = []def toggle_text(button_num): button = button_list[button_num] label = label_list[button_num] if button['text'] == 'WL': button['text'] = 'WYL' label['bg'] = 'green' else: button['text'] = 'WL' label['bg'] = 'red'root = tk.Tk()root.title('GUI - TEST')for i in range(NUM_BUTTONS): # create widgets def _wrapper(button_num=i): # default argument value is current index toggle_text(button_num) button = tk.Button(text='WL', width=12, bg='red', command=_wrapper) button.grid(row=i, column=1) button_list.append(button) label = tk.Label(text=i+1, width=6, bg='red') label.grid(row=i, column=2) label_list.append(label)root.mainloop()
In the code above, the text of each tk.Label
is set via the text=i+1
argument in the
label = tk.Label(text=i+1, width=6, bg='red')
statement. To give each label its own arbitrary text value, you could define another list containing the text for each label, for example:
label_text_list = ['L1', 'L2', 'L3', ...]
and then use
label = tk.Label(text=label_text_list[i], width=6, bg='red')
in the loop instead.
Also see Generate Tkinter buttons dynamically for another example.
I'd suggest making a class for your button, there are loads of tutorials on classes, here's one that really helped me:
An object-oriented way to do what you want is to create a class that contains one or more GUI widgets and defines methods that operate upon them. The is considered a more advanced technique, but using it will make modifying and enhancing your program later easier.
For example, you could make the background color a variable rather than hardcoding it to be 'red'
by simply by adding another argument to the __init__()
method and passing a value for it when creating instances.
The following does the same thing as your script (and my other answer). The tk.Button
in each instance of a MyWidget
will call that instance's __call__()
method when it's clicked due to the command=self.__call__
argument used when the Button
is created.
import Tkinter as tkNUM_MY_WIDGETS = 3class MyWidget(object): def __init__(self, row, column, label_text): self.button = tk.Button(text='WL', width=12, bg='red', command=self.__call__) self.button.grid(row=row, column=column) self.label = tk.Label(text=label_text, width=6, bg='red') self.label.grid(row=row, column=column+1) def __call__(self): if self.button['text'] == 'WL': self.button['text'] = 'WYL' self.label['bg'] = 'green' else: self.button['text'] = 'WL' self.label['bg'] = 'red'root = tk.Tk()root.title('GUI - TEST')widgets = []for i in range(NUM_MY_WIDGETS): # create widgets widgets.append(MyWidget(i, 1, i+1))root.mainloop()