I'm trying to write an app in Python Tkinter where you input text through a text field, then displays labels for each character from the input text.
from tkinter import *
array = []
root = Tk()
root.title('app interface')
inpframe = LabelFrame(root, text="input", padx=100, pady=20)
inpframe.pack()
outframe = LabelFrame(root, text="output", padx=100, pady=100)
outframe.pack()
c = " "
def on_enter(e):
e.widget['background'] = 'green'
c = e.widget['text']
currentchar = Label(inpframe, text=c)
currentchar.grid(row=1, column=1)
def on_leave(e):
e.widget['background'] = 'SystemButtonFace'
currentchar = Label(inpframe, text=" ")
currentchar.grid(row=1, column=1)
inp = Entry(inpframe)
inp.grid(row=0, column=0)
def enterText():
array.clear()
inptxt = inp.get().lower()
myLabel = Label(inpframe, text=inptxt)
myLabel.grid(row=1, column=0)
for i in inptxt:
array.append(i)
for i in range(0, len(array), 1):
array[i] = Button(outframe, text=array[i], height=10, width=5)
array[i].grid(row=2, column= i, padx=5, pady=10)
array[i].bind("<Enter>", on_enter)
array[i].bind("<Leave>", on_leave)
myButton = Button(inpframe, text="Enter", command=enterText)
myButton.grid(row=0, column=1)
root.mainloop()
Here's the problem. When I input text shorter than the previous text, the shorter text gets displayed, but the remaining text from the previous text remains on the interface enter image description here. For example, when I type "world", the app displays w o r l d. But when I type "hi", the app displays h i r l d
CodePudding user response:
I see that the label holding the text is also left behind the newly entered text. You can simply create the label in the global scope and then configure the text each time you enter a new text.
As for the buttons; there is a simple way to destroy all children of a widget, as exemplified below.
from tkinter import *
array = []
root = Tk()
root.title('app interface')
inpframe = LabelFrame(root, text="input", padx=100, pady=20)
inpframe.pack()
outframe = LabelFrame(root, text="output", padx=100, pady=100)
outframe.pack()
inp = Entry(inpframe)
inp.grid(row=0, column=0)
myLabel = Label(inpframe) # Create label in the global scope
myLabel.grid(row=1, column=0)
c = " "
def on_enter(e):
e.widget['background'] = 'green'
c = e.widget['text']
currentchar = Label(inpframe, text=c)
currentchar.grid(row=1, column=1)
def on_leave(e):
e.widget['background'] = 'SystemButtonFace'
currentchar = Label(inpframe, text=" ")
currentchar.grid(row=1, column=1)
def enterText():
array.clear()
inptxt = inp.get().lower()
myLabel.config(text=inptxt) # Configure label for new text
# Delete all current buttons
for widget in outframe.winfo_children():
widget.destroy()
for i in inptxt:
array.append(i)
for i in range(0, len(array), 1):
array[i] = Button(outframe, text=array[i], height=10, width=5)
array[i].grid(row=2, column= i, padx=5, pady=10)
array[i].bind("<Enter>", on_enter)
array[i].bind("<Leave>", on_leave)
myButton = Button(inpframe, text="Enter", command=enterText)
myButton.grid(row=0, column=1)
root.mainloop()
Alteratly you can loop throug the array and delete each button before you clear array:
# Delete all current buttons
for i in array:
i.destroy()
array.clear()