Reputation: 281
I have a Text widget (my_text
) in my program that should only accept certain characters. If the user enters a character that isn't defined in a dictionary (ACCEPTED
), the program should either ignore the input entirely or, at the very least, remove the character right after it's been entered. Otherwise, the program should output the corresponding value into my_text2
.
I'm doing my best to also ensure that my program accounts for text entered before the end of the text content. For example, say a user goes back and inserts text in the middle of a sentence; this program should still function as expected. This is an example of the logic I'm working with:
import tkinter as tk
# For this example, I'm converting the output from
# a QWERTY keyboard to the output of a Dvorak keyboard.
ACCEPTED = {
"q": "'",
"w": ",",
"e": ".",
"r": "p",
"t": "y",
"y": "f",
# ...
}
def handle_input(s):
my_text2.configure(state = tk.NORMAL)
if s.char in set(ACCEPTED):
my_text2.insert(
my_text.index(tk.INSERT),
ACCEPTED[s.char]
)
elif s.keysym.lower() in {"backspace", "delete"}:
my_text2.delete(
my_text.index(tk.INSERT)
+ "-1c" * (s.keysym.lower() == "backspace")
)
# This is the part I'm missing.
else:
pass
my_text2.configure(state = tk.DISABLED)
root = tk.Tk()
root.geometry("648x163+10+10")
my_text = tk.Text(
root,
width = 40,
height = 10,
)
my_text.bind("<Key>", handle_input)
my_text2 = tk.Text(
root,
width = 40,
height = 10,
state = tk.DISABLED,
)
my_text.grid(column = 0, row = 0)
my_text2.grid(column = 1, row = 0)
root.mainloop()
These two Text widgets must remain synced for my program to function properly.
So far, I've tried my_text.delete(tk.INSERT)
, my_text.delete(tk.CURRENT)
, and a "-1c"
variant of both. I'm still fairly new to Tkinter, so I'm not sure what's going on. It looks to me like the text isn't actually entered into my_text
until after handle_input()
runs, meaning that there won't be anything to delete. When I enter a character that isn't defined in ACCEPTED
, it still shows up in my_text
, which desyncs the two Text widgets.
Everywhere where I've found a similar issue, the problem at hand doesn't account for text before tk.END
, but I'm trying to match up these two Text widgets perfectly, so tk.END
won't work for me.
Upvotes: 0
Views: 1736
Reputation: 7680
Returning "break"
from a function that is called from an event, will stop the event. That means that tkinter
's widget will never get the event.
Upvotes: 1