I am trying to develop a GUI in Python with TKinter. I have a grid of buttons and I want to write some code which enables me to write callback functions in a systematic way, rather than having to manually define 13 callback functions for each of the buttons. (There are 13 of them in this grid.)
I am fairly sure this is a standard pattern, I just don't know how to do it in Python.
I guess that it involves some way of passing data to a single callback function? I searched how to do this and the easiest method appeared to be to use a lambda. (Which I am familiar with from C++.)
I'm not quite as hot on Python however, and this first attempt didn't work. If you run it you should find that it always prints "Button 12" regardless of which button is pressed.
I think it should be fairly obvious from the code what this is supposed to do?
Perhaps the callback function / lambda has to refer to a non-member function? Decided to ask a question as I'm not sure how to proceed here and I don't know enough about the details of the language to figure it out.
#!/usr/bin/env python3
import tkinter
# this class manages the GUI
class Application(tkinter.Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.createWidgets()
def createWidgets(self):
self.master.columnconfigure(0, weight=1)
self.master.columnconfigure(1, weight=1)
self.master.columnconfigure(2, weight=1)
self.master.columnconfigure(3, weight=1)
self.master.columnconfigure(4, weight=1)
self.master.columnconfigure(5, weight=1)
self.master.rowconfigure(0, weight=1)
self.master.rowconfigure(1, weight=1)
self.master.rowconfigure(2, weight=1)
self.master.rowconfigure(3, weight=1)
self.master.rowconfigure(4, weight=1)
self.num_buttons = 13
button_text = []
for i in range(self.num_buttons):
text = "Button " + str(i)
button_text.append(text)
self.buttons = []
for i in range(self.num_buttons):
self.buttons.append(None)
self.buttons[i] = tkinter.Button(self.master, text=button_text[i], command=lambda: self.clickButton(i), height=1, width=8)
c = i % 6
r = i // 6 + 1
self.buttons[i].grid(row=r, column=c)
def clickButton(self, args):
print(self.buttons[args].cget("text"))
def main():
root = tkinter.Tk()
root.title("Application")
root.geometry("800x600")
app = Application(master = root)
while True:
app.update_idletasks()
app.update()
if __name__ == '__main__':
main()