Search code examples
pythontkinterkeyboard-eventstkinter-entry

Using backspace across multiple tkinter Entry widgets


I made wordle (using tkinter) in a previous project of mine, and now instead of using one entry to get the guess, I want 5 entries linked together that work like the blocks in:

screenshot

In the image, you can backspace across these "linked" entries. I got the typing across entries figured out, but how do I delete across them?

from tkinter import *

root = Tk()
root.geometry('400x400')


def testlen():
    global textinentry1, textinentry2, textinentry3, textinentry4, textinentry5
    textinentry1= entry1.get()
    textinentry2= entry2.get()
    textinentry3= entry3.get()
    textinentry4= entry4.get()
    textinentry5= entry5.get()
    if len(textinentry1)  >1 :
        entry1.delete(0,END)
        entry1.insert(0,textinentry1[0])
        entry2.delete(0, END)
        entry2.insert(0,textinentry1[1] )
        entry2.focus_set()
    if len(textinentry2)  >1 :
        entry2.delete(0,END)
        entry2.insert(0,textinentry2[0])
        entry3.delete(0, END)
        entry3.insert(0,textinentry2[1] )
        entry3.focus_set()
    if len(textinentry3)  >1 :
        entry3.delete(0,END)
        entry3.insert(0,textinentry3[0])
        entry4.delete(0, END)
        entry4.insert(0,textinentry3[1] )
        entry4.focus_set()
    if len(textinentry4)  >1 :
        entry4.delete(0,END)
        entry4.insert(0,textinentry4[0])
        entry5.delete(0, END)
        entry5.insert(0,textinentry4[1] )
        entry5.focus_set()
    if len(textinentry5) > 1:
        entry5.delete(0,END)
        entry5.insert(0,textinentry5[0])


entry1 = Entry(root,width=3,  font = ('Georgia 18'), justify=CENTER)
entry1.grid(row=0, column=0)
entry2 = Entry(root, width=3,  font = ('Georgia 18'), justify=CENTER)
entry2.grid(row=0, column=1)
entry3 = Entry(root, width=3, font = ('Georgia 18'), justify=CENTER)
entry3.grid(row=0, column=2)
entry4 = Entry(root, width=3, font = ('Georgia 18'), justify=CENTER)
entry4.grid(row=0, column=3)
entry5 = Entry(root, width=3, font = ('Georgia 18'), justify=CENTER)
entry5.grid(row=0, column=4)

def loop():
    testlen()
    root.after(1,loop) # 1 is 1 millisecond. Here root.after method calls the loop
                       # function after 1 millisecond without crashing your code.

loop()

root.mainloop()


Solution

  • First, you have to get something to register a button press. For this, I imported keyboard and used if keyboard.is_pressed("backspace"): to see if backspace was pressed.

    Unfortunately, when a human presses a button, we hold it down for a few milliseconds so to the computer, we press it more then once. To prevent this, I imported time and found that using time.sleep(.15)was the best delay because it stopped me from accidentally pressing it more then once, and I could also hold it down without the code slowly erasing each character.

    This could be better condensed with a loop but my code for the standalone boxes is:

    from tkinter import *
    
    import keyboard, time
    
     
    
    root = Tk()
    
    root.geometry('400x400')
    
     
    
     
    
    def testlen():
    
        global textinentry1, textinentry2, textinentry3, textinentry4, textinentry5, whathasfocus
    
        whathasfocus= root.focus_get()
    
        textinentry1= entry1.get()
    
        textinentry2= entry2.get()
    
        textinentry3= entry3.get()
    
        textinentry4= entry4.get()
    
        textinentry5= entry5.get()
    
     
    
        if whathasfocus == entry1:
    
            if len(textinentry1) >= 1:
    
                pass
    
            elif len(textinentry1) == 0:
    
                if keyboard.is_pressed("delete"):
    
                    time.sleep(.15)
    
                    entry1.delete(0,END)
    
                    entry1.focus_set()
    
     
    
        if whathasfocus == entry2:                    
    
            if len(textinentry2) >= 1:
    
                    pass
    
            elif  len(textinentry2) == 0:
    
                if keyboard.is_pressed("backspace"):
    
                    time.sleep(.15)
    
                    entry2.delete(0,END)
    
                    entry1.focus_set()
    
                if keyboard.is_pressed("delete"):
    
                    time.sleep(.15)
    
                    entry2.delete(0,END)
    
                    entry2.focus_set()
    
        if whathasfocus == entry3:
    
            if len(textinentry3) >= 1:
    
                pass
    
            elif  len(textinentry3) == 0 :
    
                if keyboard.is_pressed("backspace"):
    
                    time.sleep(.15)
    
                    entry3.delete(0,END)
    
                    entry2.focus_set()
    
                if keyboard.is_pressed("delete"):
    
                    time.sleep(.15)
    
                    entry3.delete(0,END)
    
                    entry3.focus_set()
    
        if whathasfocus == entry4:
    
            if len(textinentry4) >= 1:
    
                pass
    
            elif len(textinentry4) == 0:
    
                if keyboard.is_pressed("backspace"):
    
                    time.sleep(.15)
    
                    entry4.delete(0,END)
    
                    entry3.focus_set()
    
                if keyboard.is_pressed("delete"):
    
                    time.sleep(.15)
    
                    entry4.delete(0,END)
    
                    entry4.focus_set()
    
        if whathasfocus == entry5:
    
            if len(textinentry5) >= 1:
    
                pass
    
            elif  len(textinentry5) == 0: 
    
                if keyboard.is_pressed("backspace"):
    
                    time.sleep(.15)
    
                    entry5.delete(0,END)
    
                    entry4.focus_set()
    
        
    
        if len(textinentry1)  >1 :
    
            entry1.delete(0,END)
    
            entry1.insert(0,textinentry1[0])
    
            entry2.delete(0, END)
    
            entry2.insert(0,textinentry1[1] )
    
            entry2.focus_set()
    
        if len(textinentry2)  >1 :
    
            entry2.delete(0,END)
    
            entry2.insert(0,textinentry2[0])
    
            entry3.delete(0, END)
    
            entry3.insert(0,textinentry2[1] )
    
            entry3.focus_set()
    
        if len(textinentry3)  >1 :
    
            entry3.delete(0,END)
    
            entry3.insert(0,textinentry3[0])
    
            entry4.delete(0, END)
    
            entry4.insert(0,textinentry3[1] )
    
            entry4.focus_set()
    
        if len(textinentry4)  >1 :
    
            entry4.delete(0,END)
    
            entry4.insert(0,textinentry4[0])
    
            entry5.delete(0, END)
    
            entry5.insert(0,textinentry4[1] )
    
            entry5.focus_set()
    
        if len(textinentry5) > 1:
    
            entry5.delete(0,END)
    
            entry5.insert(0,textinentry5[0])
    
     
    
     
    
    entry1 = Entry(root,width=3,  font = ('Georgia 18'), justify=CENTER)
    
    entry1.grid(row=0, column=0)
    
    entry1.focus_set()
    
    entry2 = Entry(root, width=3,  font = ('Georgia 18'), justify=CENTER)
    
    entry2.grid(row=0, column=1)
    
    entry3 = Entry(root, width=3, font = ('Georgia 18'), justify=CENTER)
    
    entry3.grid(row=0, column=2)
    
    entry4 = Entry(root, width=3, font = ('Georgia 18'), justify=CENTER)
    
    entry4.grid(row=0, column=3)
    
    entry5 = Entry(root, width=3, font = ('Georgia 18'), justify=CENTER)
    
    entry5.grid(row=0, column=4)
    
     
    
    def loop():
    
        testlen()
    
        root.after(1,loop) # 1 is 1 millisecond. Here root.after method call the loop function after 1 millisecond without crashing your code.
    
     
    
    loop()
    
    root.mainloop()