Python 3.1
I'm trying to validate that the string input to a ttk.Entry widget can be turned into a float. The simple code below shows that the validate function is successful in its task, and is returning true/false correctly.
I understood it to be the case that if the Entry widget gets 'false' back from its validatecommand, it should revert to whatever was stored in the textvariable before the attempted entry happened.
But that's not happening - the new entry appears, even though it's invalid.
Presumably I am missing something foolish...
from tkinter import *
from tkinter.ttk import *
root = Tk()
text = StringVar()
text.set('100.0')
def validate(inp):
print(inp)
if inp in '0123456789.-+':
try:
float(inp)
print('float')
return True
except ValueError:
print('notfloat')
return False
else:
print('notfloat')
return False
vcmd = root.register(validate)
a = Entry(textvariable = text,
validate = 'focusout',
validatecommand = (vcmd,'%P'))
a.pack()
b = Entry()
b.pack()
root.mainloop()
Try following:
from tkinter import *
from tkinter.ttk import *
root = Tk()
text = StringVar()
text.set('100.0')
def validate(inp):
try:
float(inp)
except ValueError:
return False
return True
vcmd = root.register(validate)
a = Entry(textvariable=text,
validate='key',
validatecommand=(vcmd, '%P'))
a.pack()
b = Entry()
b.pack()
root.mainloop()
I used validate='key'
instead.
and replaced validate
function. a in b
check substring a
in contained in b
.
>>> '100.00' in '0123456789.-+'
False
>>> '100.00' in 'blah blah 100.00 blah blah'
True
ALTERNATIVE
using focusout
:
from tkinter import *
from tkinter.ttk import *
root = Tk()
text = StringVar()
text.set('100.0')
last_ok_value = text.get()
def validate(inp):
global last_ok_value
try:
float(inp)
except ValueError:
return False
last_ok_value = inp
return True
def invalidate():
text.set(last_ok_value)
vcmd = root.register(validate)
ivcmd = root.register(invalidate)
a = Entry(textvariable=text,
validate='focusout',
validatecommand=(vcmd, '%P'),
invalidcommand=(ivcmd,))
a.pack()
b = Entry()
b.pack()
root.mainloop()
Using class:
from tkinter import *
from tkinter.ttk import *
class FloatEntry(Entry):
def __init__(self, *args, **kwargs):
initial_value = kwargs.pop('initial_value', '100.00')
assert self.validate(initial_value), 'Invalid initial_value given'
self.last_valid_value = initial_value
self.text = StringVar(value=initial_value)
Entry.__init__(self, *args, textvariable=self.text, **kwargs)
self.vcmd = self.register(self.validate)
self.ivcmd = self.register(self.invalidate)
self['validate'] = 'focusout'
self['validatecommand'] = self.vcmd, '%P',
self['invalidcommand'] = self.ivcmd,
def validate(self, inp):
try:
float(inp)
except ValueError:
return False
self.last_valid_value = inp
return True
def invalidate(self):
self.text.set(self.last_valid_value)
root = Tk()
FloatEntry(initial_value='100.0').pack()
Entry().pack()
root.mainloop()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.