Home > OS >  Using backspace across multiple tkinter Entry widgets
Using backspace across multiple tkinter Entry widgets

Time:05-17

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()

CodePudding user response:

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 == entry2 and len(textinentry2) == 0:
        if keyboard.is_pressed("backspace"):
            time.sleep(.15)
            entry1.delete(0,END)
            entry1.focus_set()
    elif whathasfocus == entry3 and len(textinentry3) == 0:
        if keyboard.is_pressed("backspace") :
            time.sleep(.15)
            entry2.delete(0,END)
            entry2.focus_set()
    elif whathasfocus == entry4 and len(textinentry4) == 0:
        if keyboard.is_pressed("backspace") :
            time.sleep(.15)
            entry3.delete(0,END)
            entry3.focus_set()
    elif whathasfocus == entry5 and len(textinentry5) == 0:
        if keyboard.is_pressed("backspace") :
            time.sleep(.15)
            entry4.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()
  • Related