Restricting user entry in Entry field in Tkinter without 'disabled' method
One of the way is to create a custom class inherited from Entry
and override the insert()
:
import tkinter as tk
...
class MyEntry(tk.Entry):
def __init__(self, master=None, **kw):
super().__init__(master, **kw)
# make it disabled, but with black on white like in normal state
self.config(state='disabled', disabledforeground='black', disabledbackground='white')
def insert(self, pos, value):
self.config(state='normal')
super().insert(pos, value)
self.config(state='disabled')
def delete(self, first, last=None):
self.config(state='normal')
super().delete(first, last)
self.config(state='disabled')
...
field = MyEntry(...) # use MyEntry instead of tk.Entry
...
It still uses 'disabled' state, but you don't need to change the other parts of your application.
How to restrict Text widget input to certain characters with Tkinter?
Returning "break"
from a function that is called from an event, will stop the event. That means that tkinter
's widget will never get the event.
How to restrict the maximum number a user can enter in an entry widget?
In this case , try using SpinBox Instead of Entry Widget .
For example :
from tkinter import *
top = Tk()
top.geometry("200x200")
spin = Spinbox(top, from_= 0, to = 25)
spin.pack()
top.mainloop()
To get the SpinBox current value , you can just simply do : spin.get()
Tkinter: restrict entry data to float
The right tool is definitely the re
module.
Here is a regular expression that should do the job:
(\+|\-)?\d+(,\d+)?$
Let's break it down:
(\+|\-)?\d+(,\d+)?$
\+|\- Starts with a + or a -...
( )? ... but not necessarily
\d+ Contains a repetition of at least one digits
,\d+ Is followed by a comma and at least one digits...
( )? ... but not necessarily
$ Stops here: nothing follows the trailing digits
Now, your validate
function only has to return True
if the input matches that regex, and False
if it does not.
def validate(string):
result = re.match(r"(\+|\-)?\d+(,\d+)?$", string)
return result is not None
Some tests:
# Valid inputs
>>> validate("123")
True
>>> validate("123,2")
True
>>> validate("+123,2")
True
>>> validate("-123,2")
True
# Invalid inputs
>>> validate("123,")
False
>>> validate("123,2,")
False
>>> validate("+123,2,")
False
>>> validate("hello")
False
Edit
I understand now that you want to check in real-time if the input is valid.
So here is an example of what you can do:
import tkinter as tk
import re
def validate(string):
regex = re.compile(r"(\+|\-)?[0-9,]*$")
result = regex.match(string)
return (string == ""
or (string.count('+') <= 1
and string.count('-') <= 1
and string.count(',') <= 1
and result is not None
and result.group(0) != ""))
def on_validate(P):
return validate(P)
root = tk.Tk()
entry = tk.Entry(root, validate="key")
vcmd = (entry.register(on_validate), '%P')
entry.config(validatecommand=vcmd)
entry.pack()
root.mainloop()
The validate
function now checks more or less the same thing, but more loosely.
Then if the regex results in a match, some additional checks are performed:
- Allow the input to be empty;
- Prevent the input to have more than one
'+'
/'-'
, and more than one','
; - Ignore a match against the empty string, because the pattern allows it, so
"a"
would result in a match but we don't want it.
The command is registered, and works with the '%P'
parameter, that corresponds to the string if the input were accepted.
Please not however that forcing the input to be always correct is somewhat harsh, and might be counter-intuitive.
A more commonly used approach is to update a string next to the entry, and have the user know when their input is valid or invalid.
Related Topics
How Can a Recursive Regexp Be Implemented in Python
How Do Chained Comparisons in Python Actually Work
How to Get All Combinations of Length N in Python
How to Check Whether a Variable Is a Class or Not
Difference Between Python3 and Python3M Executables
Matching Any Character Including Newlines in a Python Regex Subexpression, Not Globally
How to Open a File Through Python
How to Extract Info Within a #Shadow-Root (Open) Using Selenium Python
Pandas To_Datetime Parsing Wrong Year
How to Remove Leading and Trailing Zeros in a String? Python
Managing Dynamic Plotting in Matplotlib Animation Module
Preprocessing in Scikit Learn - Single Sample - Depreciation Warning
Python Split a String with at Least 2 Whitespaces
What's the Difference Between 'R+' and 'A+' When Open File in Python