I have been following closely, a YouTube video in order to create an on-screen keyboard using tkinter.
I understand most of what is going on; create our buttons within a list and loop through those buttons, inserting rows at the best position to create a good looking keyboard.
The only problem I've been having with this task, is when I click a button, the text of the button gets inserted into an Entry box via tkinter.
The way in which we do this, is to assign a command to the button, and upon pressing it, calls an anonymous function, assigning the button that we pressed to the 'x' parameter. We then pass this parameter to another method and insert the value into the Entry widget.
I'm trying to understand, why can't we just pass in the button itself, but instead we have to assign the button to a parameter...
self.textbox = textbox
row=0
col=0
buttons = [
'1','2','3','4','5','6','7','8','9','0',
'q','w','e','r','t','y','u','i','o','p',
'a','s','d','f','g','h','j','k','l',
'z','x','c','v','b','n','m','end']
for button in buttons:
# why not the following command instead?
# command = lambda: self.command(button)
command = lambda x=button: self.callback(x)
if button != 'end':
tk.Button(self, text=button, width=5,
command=command).grid(row=row, column=col)
col+=1
if col > 9:
col=0
row+=1
def command(self, button):
x = button
self.callback(x)
def callback(self, value):
self.textbox.insert(tk.END, value)
With the above code, I can successfully insert the desired value into my entry widget. However, if we use the code I have commented out, it will instead insert 'end' to the entry widget.
I have tried to replicate the lambda function into a separate method, but I am still inserting an 'end' into my entry widget.
# using the commented code above and passing in button as the parameter
def command(self, button):
x = button
self.callback(x)
def callback(self, value):
self.textbox.insert(tk.END, value)
I thought If I was able to replicate the function into a non-anon function, then it would work, but clearly it is not.
What exactly is my lambda function doing it and is there a way to replicate it by using a non-anonymous function (ie. method)?