Closed thothloki closed 4 years ago
Here for your reference, not sure is it good for you.
import PySimpleGUI as sg
def valid(text):
if len(text)==1 and text in '+-':
return True
else:
try:
number = float(text)
return True
except:
return False
font = ('Helvetica', 20)
layout = [[sg.InputText('', size=(40, 1), font=font, key='-INPUT-', enable_events=True)],
[sg.Button('Exit', font=font)]]
window = sg.Window('Test', layout)
while True:
event, values = window.read()
print(event, values)
if event in (sg.WINDOW_CLOSED, 'Exit'):
break
elif event == '-INPUT-':
text = values['-INPUT-']
if not valid(text):
window['-INPUT-'].update(value=text[:-1])
window.close()
Jason's got it right. This is how input validation is done in PySimpleGUI. There is a Cookbook Recipe that shows you one way of doing this that you'll find here: https://pysimplegui.readthedocs.io/en/latest/cookbook/#recipe-input-validation
Generally speaking, the quick and dirty way is to use a simple try/except block. Let Python tell you if it's an int.
import PySimpleGUI as sg
layout = [ [sg.Text('Input only int point numbers')],
[sg.Input(key='-IN-', enable_events=True)],
[sg.Button('Exit')] ]
window = sg.Window('Int input validation', layout)
while True:
event, values = window.read()
if event in (sg.WIN_CLOSED, 'Exit'):
break
# if last character in input element is invalid, remove it
if event == '-IN-' and values['-IN-']:
try:
in_as_int = int(values['-IN-'])
except:
if not (len(values['-IN-']) == 1 and values['-IN-'][0] == '-'):
window['-IN-'].update(values['-IN-'][:-1])
window.close()
Thank you both!!! I am trying out PySimpleGUI with an app I already wrote with appJar and was just trying to find an equivalent to its NumericEntry()
I will give that a try and see how well it works.
both of your ways work very well!!! Thank you very very much. Now to just add that to about 100 inputs (for loop, here i come!)
I know this is probably python 101, using this implementation to validate an input text box. How would/could I make this more generic to handl over 100 boxes?
It depend on how you get input for 100 boxes !
For example, you have 100 boxes in window at the same time, you can set key of each box start with 'INT_', like 'INT_01', 'INT_02', ...
layout = [[sg.Input(key=f'INT_{j}{i}', enable_events=True) for i in range(10)] for j in range(10)]
then the loop event handler can be
elif event.startswith('INT_'):
...
Difference case maybe with different way to go !
You can also use tuples as keys.... key=(i,j).
Or if you don't need a row, col kind of thing and it's just 100 inputs in a row, but you want to know it's an input.... it could be
layout = [[sg.Input(key=('INT', i), enable_events=True) for i in range(100)]]
# event loop...
if hasattr(event, tuple): # if you will have both strings and tuples as keys, check for tuple first
if event[0] == 'INT': # You'll know this is one of the inputs to check for int only
# do the int check / fixup here
It's the exact same kind of mechanism Jason has shown, but with tuples instead of strings. I do like the string version as it requires only 1 check.
Oh, actually, you can safely use a [ ] index into both a string and a tuple, so you maybe don't check for the tuple, but instead check for the first position being "INT". If it's a string, event[0] will be a single character.
if event[0] == 'INT': # You'll know this is one of the inputs to check for int only
# do the int check / fixup here
I know this is probably python 101, using this implementation to validate an input text box. How would/could I make this more generic to handl over 100 boxes?
If useful, I have empowered the code above reported to check from a list of keys if the input is a float or int:
import PySimpleGUI as sg
def valid_float(text):
if len(text)==1 and text in '+-':
return True
else:
try:
number = float(text)
return True
except:
return False
def valid_int(text):
if len(text)==1 and text in '+-':
return True
else:
try:
number = int(text)
return True
except:
return False
font = ('Helvetica', 20)
layout = [[sg.InputText('', size=(40, 1), font=font, key='-INPUT-', enable_events=True)],
[sg.InputText('', size=(40, 1), font=font, key='-INPUT2-', enable_events=True)],
[sg.InputText('', size=(40, 1), font=font, key='-INPUT3-', enable_events=True)],
[sg.Button('Exit', font=font)]]
window = sg.Window('Test', layout)
while True:
event, values = window.read()
if event in (sg.WINDOW_CLOSED, 'Exit'):
break
# check input(s): float
check_float=['-INPUT-','-INPUT2-'] # a list with key(s) to check
for key in check_float:
if event == key:
text = values[key]
if not valid_float(text):
window[key].update(value=text[:-1])
# check input(s): int
check_int=['-INPUT3-'] # a list with key(s) to check
for key in check_int:
if event == key:
text = values[key]
if not valid_int(text):
window[key].update(value=text[:-1])
window.close()
Type of Issues (Question)
Operating System (all)
Python version (3.8)
PySimpleGUI Port and Version (4.19.0)
I am wondering if/how I can set an InputText to only accept numbers/integers. I am relatively new to PySimpleGUI but am coming over from other GUI modules like PyQt, appJar, remi and the like.