Reputation: 33
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
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
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
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