Entry check goes into infinite loop as debugger shows

Something goes wrong in the check of the email address if empty
cat figure out whats wrong, while the age check works
Thanks for any, help, hint
Regards
Rainer

"""
	test project
	erst benötigte Module laden
"""
import tkinter as tk		# für die GUI
from tkinter import ttk		# bessere widgets für die GUI
import sqlite3 as sql		# für die Datenbank
from string import digits	# alle Zahlen von 0 bis 9
import re

arial_20 =("Arial",18)
MIN_AGE = 10
MAX_AGE = 99

""" check if correct email address """
def valid_email(email_input):
	return bool(re.match( r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$',email_input))

def is_email():
	test = ent_email.get()
	if not test == "":
		if valid_email(test):
			return True
		else:
			ent_email.delete(0, tk.END)
			ent_email.focus_set()
			lbl_email_info.configure(text= "Ungültige Email Adresse")
			return False
	else:
		ent_email.focus_set()
#		lbl_email_info.configure(text="Pflichtfeld")
	return False

""" check if age in range """
def check_age():
	try:
		value = int(ent_age.get())
		""" here if it is INT """
		if  MIN_AGE <= value <= MAX_AGE:
			lbl_age_info.configure(text="OK")
	#		lbl_gender.focus_set()
			return True
		else:
			lbl_age_info.configure(text=f"Alter {value} ungültig")
			ent_age.delete(0, tk.END)
			ent_age.focus_set()
			#return False
	except:
		ValueError: "nn"
		lbl_age_info.configure(text="Nur Ziffern")
		ent_age.delete(0,tk.END)
		ent_age.focus_set()
		#return False
	return False
root = tk.Tk()
root.title('User im System')
root.geometry("800x400+50+50")
root.minsize(width=900, height=400)
root.maxsize(width=1000, height=600)

""" E-MAil Address """
lbl_email = ttk.Label(root, text="E-Mail:* ", width=10, font=arial_20,padding=5)
lbl_email.grid(row=0, column=0, padx='5', pady='5')

ent_email = ttk.Entry(root,width=40,font=arial_20, justify="left", validatecommand=is_email, validate="focusout")
ent_email.grid(row=0, column=1, padx='5', pady='5',sticky="w")

lbl_email_info = ttk.Label(root, text="_", width=20, font=arial_20, padding=5)
lbl_email_info.grid(row=0, column=3, padx='5', pady='5')

""" Age """
lbl_age = ttk.Label(root, text="Alter: ", width=10, font=arial_20,padding=5)
lbl_age.grid(row=1, column=0, padx='5', pady='5')

ent_age = ttk.Entry(root,width=2,font=arial_20, validatecommand=check_age, validate="focusout")
ent_age.grid(row=1, column=1, padx='5', pady='5',sticky="w")

lbl_age_info = ttk.Label(root, text="zwischen 10 und 99", width=20, font=arial_20, padding=5)
lbl_age_info.grid(row=1, column=3, padx='5', pady='5')

root.mainloop()

Suppose the focus is in the email field and you then move the focus into the age field.

The validation callback for the email field is triggered.

If the contents of the email field isn’t valid, you tell it to move the focus back into the email field, which means that must leave the age field.

However, when the focus leaves the age field, the validation callback for the age field is triggered.

If the contents of the age field isn’t valid, you tell it to move the focus back into the age field, which means that must leave the email field.

And so the focus is bounced back and forth between the email and age fields forever.

This regex is incorrect. Try this instead:

return '@' in email_input

It’s more reliable.

Also, this is probably not doing what you want:

Not sure what you intended there, maybe except ValueError: ?

Deleting someone’s input when it fails validation is poor UX. I would advise just setting the focus back there, not emptying the fields.

If those suggestions don’t solve your problem, it would help us a LOT if you say what the problem actually is.

Matthew Barnett

Yes that seams the problem, I first testet the age and it worked, the I implemented the email, so did not look at the email
Thank you

@[Chris Angelico]
I am programming since years in assembler C++, PHP and others, but I am quit new in Python beside some smal scripts in the last years but never GUI
This s a test project to learn GUI, entry validation and sqlite. So I just try to make a GUI to enter Data, validate them and write to the database and read them laster.
So it is not as important if thr regex is correct.
the “nn” in the except is just there to get no errors, I still have to learn what to enter there

My Problem is solved so far as i know the reason for the infinit loop. I have to find out how to fix or whats a better solution.
One ist to check all fields at the when the, still missing save button ist pressed , but I thougt it may be nice to check special field as valid email or age in range directly, In the full script there are other fields like name , password etc. I just check the max length direczt with a class U found on the net and planed to check them at the end
Thank you both for the perfect help
Regards
Rainer

What I tend to do is something like this:

import tkinter as tk

def on_change(*args):
    email_ok = "@" in email_var.get()
    ok_button["state"] = "normal" if email_ok else "disabled"

root = tk.Tk()

email_var = tk.StringVar()
email_var.trace("w", on_change)
ent_email = tk.Entry(root, width=40, font="arial 20", justify="left", textvariable=email_var)
ent_email.pack(side="left")

ok_button = tk.Button(root, text="OK")
ok_button.pack(side="left")

# Clear the email field.
email_var.set("")

root.mainloop()

This will disable the OK button if the email field isn’t valid.

Thank you, looks good, I will try to Implement ist. As I wrote it a test project to learn, but I have two other real projects in mind, where I need parts similar to parts in that test project.

Regards
Rainer

Hello Matthew,

thanks again for that tip. I modified it quit a lot to fit that what I wanted, but hold the trace concept. everything works fine now.

Thumps Up

Regards
Rainer