Reputation: 67
I am very new to Python an tkinter. I am developing a keyboard using tkinter. I have created a text box and I am trying to bind keys to it so that users can use keyboard for input. I want to print different keys when a key is pressed. For an example, I want to print P when 'p' is pressed, A when 'a' is pressed. I know I can manually type in each key and add a function to print the required value but that would be time consuming so I decided to use a dictionary.
Below is the code for this.
def print_letter(letter):
if letter == "backspace":
text.configure(state="normal")
value = text.get("1.0", "end")
text.delete("1.0", "end")
text.insert("1.0", value[:-2])
text.configure(state="disabled")
else:
text.configure(state="normal")
text.insert("end", letter)
text.configure(state="disabled")
letters = {
'a': 'A',
'b': 'B',
'c': 'C',
'd': 'D',
'e': 'E',
}
root = tk.Tk()
root.geometry("800x415")
root.resizable(False, False)
text = tk.Text(text_frame, width=97, height=15)
text.configure(state="disabled")
text.grid(row=0, column=0, sticky="EW")
text.focus_set()
for key, value in letters.items():
text.bind(key, lambda value: print_letter(letters.get(key)))
But only the last value in the dictionary is bounded to any key I press. I saw a few posts on SO and they all suggested the below options:
All the above gave me the same result.
Any help is appreciated.
Upvotes: 0
Views: 604
Reputation: 1
It should work:
l = []
for _ in range(10):
l.append(lambda v=_: print(v))
Upvotes: 0
Reputation: 4365
My personal preference is to use functools.partial
rather than lambda
since it freezes the arguments. Here is an example of it in practice.
import tkinter as tk
from functools import partial
# here we add an *args argument
# since tkinter will also send the keystroke
# as an argument
def print_letter(letter, *args):
if letter == "backspace":
text.configure(state="normal")
value = text.get("1.0", "end")
text.delete("1.0", "end")
text.insert("1.0", value[:-2])
text.configure(state="disabled")
else:
text.configure(state="normal")
text.insert("end", letter)
text.configure(state="disabled")
letters = {
'a': 'A',
'b': 'B',
'c': 'C',
'd': 'D',
'e': 'E',
}
root = tk.Tk()
root.geometry("800x415")
root.resizable(False, False)
text = tk.Text(root, width=97, height=15)
text.configure(state="disabled")
text.grid(row=0, column=0, sticky="EW")
text.focus_set()
for key, value in letters.items():
# partial takes unlimited args.
# The first being the function name
# and subsequent ones being the arguments
text.bind(key, partial(print_letter, value))
root.mainloop()
Upvotes: 1
Reputation: 1390
If I've understood your question correctly, you need sth. like this:
l = []
for _ in range(10):
l.append(lambda v=_: print(v))
Hope that's helpful!
Upvotes: 0