0

I have coded an app with python and tkinter. I have an entry box and I want that when the user enters a data it matches with the regex. it must match interactively. That is to say when the user enters a value which does not correspond the value must be not blocked. That's why I use focusin in the code. What I don't understand is that my entry is invalid even when the value matches the not regex In addition, the entry allows you to enter any value and not block it

Here is a working example

import tkinter as tk
import re

class FocusOutValidationDemo() :
    def __init__(self):
        self.master = tk.Tk()
        self.errormsg = tk.Label( text = '', fg = 'red' )
        self.errormsg.pack()
        tk.Label( text = 'Enter Email Address' ).pack()
        vcmd = (self.master.register( self.validate_email ), '%P')
        invcmd = (self.master.register( self.invalid_email ), '%P')
        self.emailentry = tk.Entry( self.master, validate = "focusin",validatecommand = vcmd,invalidcommand = invcmd)
        self.emailentry.pack()
        tk.mainloop()

    def validate_email(self, P):
        self.errormsg.config( text = '' )
        x = re.match( r"#\d+\s[A-Z]\d+(?:[,-][A-Z]\d+)*(?:;#\d+\s[A-Z]\d+(?:[,-][A-Z]\d+)*)*", P )
        return (x != None)

    def invalid_email(self, P):
        self.errormsg.config( text = 'Invalid' )
        self.emailentry.focus_set()

app = FocusOutValidationDemo()
Béa
  • 101
  • 2
  • 9
  • `validate = "focusin"` will validate only when the entry receives focus. Not when there is a key press or any other event occuring, ``validate = "key"`` is what you might want. – Art Jun 23 '21 at 11:07
  • yes i already try it. But when I use this option I can't press any key. The message stuck on invalid – Béa Jun 23 '21 at 11:16
  • Its ok to enter any characters as long as they are recognized as valid or invalid –  Jun 23 '21 at 11:19
  • Can you tell us what your regex is trying to match? also, can you give us an example of valid input? – Art Jun 23 '21 at 11:24
  • It is the folling of this subject https://stackoverflow.com/questions/68063592/regex-python-conditions/68090157?noredirect=1#comment120355715_68090157 . I want to match #number A4-Q78,A4,B5587 for example – Béa Jun 23 '21 at 11:31
  • You should more likely `return True` and `False`. – Delrius Euphoria Jun 23 '21 at 11:35
  • Can you give an example of a valid input – Delrius Euphoria Jun 23 '21 at 11:43
  • @CoolCloud: _"You should more likely return True and False"_ - they _are_ returning True or False. `(x != None)` will always return either True or False. – Bryan Oakley Jun 23 '21 at 14:14
  • @BryanOakley Ah yea, I missed to understand that expression, thanks :D – Delrius Euphoria Jun 23 '21 at 15:11

1 Answers1

2

Don't use validate if you don't want the entry to refuse the user's input, instead set a control variable to the Entry and use trace method to call a function to validate the entry.

import tkinter as tk
import re

class FocusOutValidationDemo() :
    def __init__(self):
        self.master = tk.Tk()
        self.errormsg = tk.Label( text = '', fg = 'red' )
        self.errormsg.pack()
        tk.Label( text = 'Enter Email Address' ).pack()

        self.var = tk.StringVar()

        self.var.trace('w', self.validate_email)

        emailentry = tk.Entry( self.master, textvariable=self.var)
        emailentry.pack()
        self.master.mainloop()

    def validate_email(self, *p):

        self.errormsg.config(text='')
        x = re.match( r"#\d+\s[A-Z]\d+(?:[,-][A-Z]\d+)*(?:;#\d+\s[A-Z]\d+(?:[,-][A-Z]\d+)*)*", self.var.get())
        if x is None:
            self.errormsg.config(text='Invalid')

app = FocusOutValidationDemo()

Art
  • 2,836
  • 4
  • 17
  • 34
  • Instead of `tk.mainloop()`, it is better to use `self.master.mainloop()`. It's just best practises, doesn't make much of a difference. – TheLizzard Jun 23 '21 at 11:38
  • @TheLizzard thank you. didn't notice that. – Art Jun 23 '21 at 11:38
  • Thank you, but this is not really what I want...because with this code the entry #15 A1, sdksdlksd is valid but in fact it is not follow the regex expression... – Béa Jun 23 '21 at 11:40
  • 1
    @Béa I didn't make any changes to the regex expression, It must be a problem with your regex. – Art Jun 23 '21 at 11:44
  • 1
    I don't think it is a problem with regex but with re.match? because even if a part matches it displays true while I want all the users input matches – Béa Jun 23 '21 at 11:54
  • 2
    @Béa yes, instead try `re.fullmatch` – Art Jun 23 '21 at 11:55
  • Super ! Is there any way to match when a key is pressed? – Béa Jun 23 '21 at 12:14
  • @Béa I don't understand what you mean. It does the matching when the key is pressed/string is changed. – Art Jun 23 '21 at 12:17