Still trying to teach myself GUI development using tkinter, I decided to try to code a simple substitution cipher app as a learning exercise.
At the core of this is the alphabet where each letter in the plaintext is mapped to a fixed letter in the ciphertext alphabet.
I would like to generate the (26 * 2) widgets (one label and one entry box) in a loop.
Whilst I can do this (see example code), I cannot work out how to access the data typed in to the entry field. I have looked at examples where buttons are generated in a loop, and the "command" is linked using a lambda function - but I can't see how to do this with entry fields.
Of course I could do:
entryA = tk.Entry(self.input_frame, width=1).grid(row=1, column=0)
entryB = tk.Entry(self.input_frame, width=1).grid(row=1, column=1)
....
entryZ = tk.Entry(self.input_frame, width=1).grid(row=1, column=25)
but that seems cumbersome and inelegant.
What I would like to achieve, I guess, is some sort of event which, when the user types a letter into a particular box, the alphabet dictionary gets updated - but how do I know which box they have typed in? I have played around with the "name" field, but got nowhere so far...
Thanks in advance.
import tkinter as tk
class App(tk.Tk):
def __init__(self, title="Sample App", *args, **kwargs):
super().__init__()
self.title(title)
self.alphabet = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
# (This will be a dictionary in the real implementation)
# Create a frame:
self.input_frame = tk.LabelFrame(self, text="The Alphabet")
self.input_frame.grid(row=0, column=0, padx=5, pady=5, sticky=tk.NSEW)
self.input_frame.columnconfigure(0, weight=1)
self.input_frame.rowconfigure(0, weight=1)
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
self.draw_alphabet()
def draw_alphabet(self):
for i in range(26): # Display each letter and an entry box to enter letter
tk.Label(self.input_frame,
text=self.alphabet[i]
).grid(row=0, column=i)
tk.Entry(self.input_frame,
width = 1,
name = f"letter{i}").grid(row=1, column=i)
if __name__ == "__main__":
App().mainloop()