D_T
D_T

Reputation: 33

Entry Tkinter is not allowing to erase data if selected all and pressed delete or backspace button

I have written a code for entry widget which doesnot allow alphabets and limits the number of digits to 7. But i am not able to select all in the entry box and delete them using delete or backspace keys, could somebody help me on this.

My code snippet:

self.DelayLabel = ttk.Label(self) self.DelayLabel["text"] = "timeout" vcmd = (root.register(self.IntLength_Delay), '%P', '%S") self.Delay = ttk.Entry(self, width = '5', validate = 'key', validatecommand = vcmd)

def IntLenght_Delay(self,value,text):
   if text in '0123456789':
       if len(value)<7:
          return True
       else:
           return False
   else:
       return False

Upvotes: 2

Views: 1926

Answers (3)

Ishrak M
Ishrak M

Reputation: 182

Working in python 3.8.

%d == '0' -> delete text | %d == '-1' -> select text

import tkinter as tk
window = tk.Tk()
window.title('tkinter Entry')

def IntLength_Delay(action, key, content, value):
    return True if not action == '1' or len(value) < 7 and (content != '' and key == '0' or key in '123456789') else False

vcmd=window.register(IntLength_Delay)

txt = tk.Entry(window,width=10,validate='key',validatecommand=(vcmd,'%d','%S','%s', '%P'))
txt.grid(column=1,row=1,sticky='news')

window.mainloop()

Upvotes: 0

erekalper
erekalper

Reputation: 887

Answering an older question here, but I was having an extremely similar problem and wound up finding a decent solution. @Bryan Oakley's answer is useful, but doesn't provide an example, which is what I aim to do here.

After importing Tkinter or tkinter (depending on your Python version) as tk, first define the initial validation command:

val_cmd = (master.register(self.validate), '%P')  # master is root in thie case.

Next, whenever you have an entry box needing validation, I found this to be a nice way to write it out:

self.entry = tk.Entry(your_frame_of_choice)
self.entry.insert('end', 100)  # Inserts 100 as an initial value.
self.entry.config(validate='key', validatecommand=val_cmd)

This inserts a value before the validation begins. I originally had something like self.entry = tk.Entry(your_frame_of_choice, validate='key', validatecommand=val_cmd), but various iterations of the validation function that I toyed with rejected the insert code if the validation came before the insert. The one listed below doesn't care, but I've kept the entry code this way as I find it more aesthetically pleasing.

Finally, the actual function:

def validate(self, input_text):
    if not input_text:
        return True
    try:
        float(input_text)
        return True
    except ValueError:
        return False

This checks for floats, but you could easily change it to ints, as you prefer. And, most importantly, it allows you to delete and write over any highlighted text in the entry box.

I'm sure the initial problem is long gone, but I hope someone in the future finds this to be helpful!

Upvotes: 2

Bryan Oakley
Bryan Oakley

Reputation: 385930

Follow the logic. let's say you've entered "987". You now select it and try to delete it. In your validation function text (the current value) will be "987". Your code isn't prepared for that so it will fail the first if statement. Since it fails, validation returns False, disallowing the edit.

You need to be prepared for what Tkinter passes to your function (a long string in the case of a deletion), and you need to explicitly allow an empty value after the edit.

Upvotes: 0

Related Questions