pythontkinterwidgettkinter-entry

Python tkinter will not delete an entry, will only delete all but the last character


This is my first time coding, please go easy.

I'm trying to make an app that will take 5 different entries. Once a button is pressed, I want these entries to be cleared. I'm currently testing with just one - "lditime". I have the input set so that it only accept (XX:XX:XX) and no more characters, and no backspaces, where X is a digit.

I've got over a thousand lines of code for the whole game so I've done my best to pick the relevant stuff out, let me know if more is needed.

import tkinter as tk

window = tk.Tk()

def validate_time(inputtime):
    if len(inputtime) == 1 and inputtime[-1].isdigit():
        return True
    if len(inputtime) == 2 and inputtime[-1].isdigit():
        return True
    if len(inputtime) == 3 and inputtime[-1] == ":":
        return True
    if len(inputtime) == 4 and inputtime[-1].isdigit():
        return True
    if len(inputtime) == 5 and inputtime[-1].isdigit():
        return True
    if len(inputtime) == 6 and inputtime[-1] == ":":
        return True
    if len(inputtime) == 7 and inputtime[-1].isdigit():
        return True
    if len(inputtime) == 8 and inputtime[-1].isdigit():
        return True
    else:
        return False

def on_validate(P):
    return validate_time(P)

def backandmessage(bs):
    if bs.keysym == "BackSpace":
        return "break"
    messagecheck()  #cmd that is irrelevant

def ldrelease():
    if (len(lditime.get()) == 8 and len(ldilat.get()) == 8 and len(ldilong.get()) == 8 and
            ((ldd1cbv.get() == 1 or ldd2cbv.get() == 1) or ldd3cbv.get() == 1 or ldd4cbv.get() == 1
             or ldd5cbv.get() == 1 or ldd6cbv.get() == 1)):
        lditime.delete(0, 8)
        ldd1.deselect()
        ldd1.configure(state="normal")
        ldd2.deselect()
        ldd2.configure(state="normal")
        ldd3.deselect()
        ldd3.configure(state="normal")
        ldd4.deselect()
        ldd4.configure(state="normal")
        ldd5.deselect()
        ldd5.configure(state="normal")
        ldd6.deselect()
        ldd6.configure(state="normal")


ldi = tk.Label(text="Load Drop Interface", font=("Helvetica", 15))
lditimet = tk.Label(text="Time", font=("Helvetica", 15))
lditime = tk.Entry(validate="key", validatecommand=(window.register(on_validate), "%P"))
lditime.bind("<KeyPress>", backandmessage)
lddrelease = tk.Button(text="Release", font=("Helvetica", 15), command=ldrelease)

window.mainloop()

I have tried using lditime.delete(0, 8) as above, lditime.delete(0, tk.END). When I use lditime.delete(0, 7) it will clear all but the last character of the entry. When I get it to print len(lditime.get()) it comes out as 8. When I print it out character by character, it is as expected (I've been using 12:12:12 as a test). I have tried using lditime.focus_force() before the deletion.

The deselect statements are running as expected, but just in case I moved the deletion to a different button that has been functioning fine. When I did this, I tried

    print(lditime.get())
    print(len(lditime.get()))
    lditime.delete(0, 8)
    print(lditime.get())
    print(len(lditime.get()))

Which gave me 8, 12:12:12, 8, 12:12:12 When I repeated it with lditime.delete(0, 7) it came out with 8, 12:12:12, 2, 1

I have wasted hours. Please help me.


Solution

  • When you call lditime.delete(0, 8), the validation function validate_time() will return False because inputtime is empty string. So nothing will be deleted.

    You need to return True when inputtime is empty string:

    def validate_time(inputtime):
        if len(inputtime) == 0:
            return True
        ...