I tried making a simple number checker that shows if the number is correct or wrong.
After some hastily written prototype code, I can't get the fields to clear.
I dug through many questions regarding this topic, but couldn't find an answer.
My attempt is in show_result()
What am I doing wrong?
It should accept the numbers, and with the last number; verify. If it's correct, show accepted-image, else show denied-image and clear Entries after wrong entry. And after 3 seconds remove the image.
I suspect the num_limit()
function messes something up, but I can't figure what.
All other files can be found here: https://bytebitten.stackstorage.com/s/JeRD33P92Us4a1Li
from tkinter import *
import time
#####
# Variables
code_check = 0
codeLength = 4
list3 = 123, 456
list4 = 2345, 3452
#####
# System
root = Tk()
root.title('Code Verifier')
root.attributes('-fullscreen', True)
root.bind('<Escape>',lambda e: root.quit())
#####
# Functions
# Input limiter function (WIP)
def num_limit(p, this_field):
global codeLength
print("Entry" + this_field + ": " + p)
this_field = int(this_field)
entries = [entry1, entry2, entry3, entry4]
next_field = entries[this_field]
# Check if it's a number
if p.isdigit():
if this_field < codeLength:
# Set focus on next field
next_field.focus_set()
pass
else:
code_checker()
return True
else:
# Check if it's Backspace or del/home/end/PgUp/PgDn
if p!="\x08" and p!="":
return False
else:
if this_field < codeLength:
next_field.focus_set()
else:
return True
def code_checker():
global code_check
global codeLength
print("== Code Check ==")
enteredCode = ''
enteredCode += entry1.get()
enteredCode += entry2.get()
enteredCode += entry3.get()
if codeLength == 3:
if enteredCode in list3:
code_check = 1
else:
code_check = 2
if codeLength == 4:
enteredCode += entry4.get()
if enteredCode in list4:
code_check = 1
else:
code_check = 2
show_result()
def show_result():
global code_check
print("== Show Result ==")
print(code_check)
# If code is correct
if code_check == 1:
# Image code accepted
main_canvas.create_image(width/2, 750, anchor=N, image=codeAccepted)
# If code is wrong
elif code_check == 2:
# Image code denied
main_canvas.create_image(width/2, 750, anchor=N, image=codeDenied)
# Clear fields
entry1.delete(0, END)
entry2.delete(0, END)
entry3.delete(0, END)
entry4.delete(0, END)
# Set focus to first field
entry1.focus_set()
else:
pass
#####
# Screen items
# Load images
codeDenied = PhotoImage(file='Assets/code_denied.png')
codeAccepted = PhotoImage(file='Assets/code_accepted.png')
# Set fullscreen canvas
main_canvas = Canvas(root, bg="#000000", bd=0, highlightthickness=0)
main_canvas.pack(fill="both", expand=True)
width = root.winfo_screenwidth()
height = root.winfo_screenheight()
# Input num limiter command
vcmd = root.register(func=num_limit)
# 3-6 single-digit input fields
entry1 = Entry(root, validate='key', validatecommand=(vcmd, '%P', 1), font=("Helvetica", 100), fg="#000000", bg="#ffffff", width=1, bd=0)
entry2 = Entry(root, validate='key', validatecommand=(vcmd, '%P', 2), font=("Helvetica", 100), fg="#000000", bg="#ffffff", width=1, bd=0)
entry3 = Entry(root, validate='key', validatecommand=(vcmd, '%P', 3), font=("Helvetica", 100), fg="#000000", bg="#ffffff", width=1, bd=0)
entry4 = Entry(root, validate='key', validatecommand=(vcmd, '%P', 4), font=("Helvetica", 100), fg="#000000", bg="#ffffff", width=1, bd=0)
# Entry position adjust
field1 = -100
field2 = 0
field3 = 100
field4 = 150
# Entry placing
if codeLength == 3:
entry_window1 = main_canvas.create_window(width+field1, 500, anchor=N, window=entry1)
entry_window2 = main_canvas.create_window(width+field2, 500, anchor=N, window=entry2)
entry_window3 = main_canvas.create_window(width+field3, 500, anchor=N, window=entry3)
elif codeLength == 4:
field1 = field1-50
field2 = field2-50
field3 = field3-50
entry_window1 = main_canvas.create_window(width/2+field1, 500, anchor=N, window=entry1)
entry_window2 = main_canvas.create_window(width/2+field2, 500, anchor=N, window=entry2)
entry_window3 = main_canvas.create_window(width/2+field3, 500, anchor=N, window=entry3)
entry_window4 = main_canvas.create_window(width/2+field4, 500, anchor=N, window=entry4)
else:
pass
#####
root.mainloop()
Inside num_limit()
, you should check whether the content of Entry
is empty or not, if it is empty return True. Without this validation, you cannot delete content of the Entry
as empty string is not a valid input.
Also you called code_checker()
before the validation function returns, so you will get empty string from Entry4
inside code_checker()
. Use after()
to schedule the execution of code_checker()
after the validation.
Finally, list3
and list4
are list of integers, but enteredCode
is string, so the checking result will always be 2. Convert enteredCode
to integer before checking.
Below are modified num_limit()
and code_checker()
:
def num_limit(p, this_field):
global codeLength
### check for empty string
if p == "": return True
print("Entry" + this_field + ": " + p)
this_field = int(this_field)
entries = [entry1, entry2, entry3, entry4]
if this_field < codeLength:
next_field = entries[this_field]
# Check if it's a number
if p.isdigit():
if this_field < codeLength:
# Set focus on next field
next_field.focus_set()
else:
# schedule execution of code_checker() after validation
root.after(100, code_checker)
return True
else:
# Check if it's Backspace or del/home/end/PgUp/PgDn
if p!="\x08" and p!="":
return False
else:
if this_field < codeLength:
next_field.focus_set()
else:
return True
def code_checker():
global code_check
global codeLength
print("== Code Check ==")
enteredCode = ''
enteredCode += entry1.get()
enteredCode += entry2.get()
enteredCode += entry3.get()
if codeLength == 3:
if int(enteredCode) in list3: # convert enteredCode to integer
code_check = 1
else:
code_check = 2
if codeLength == 4:
enteredCode += entry4.get()
if int(enteredCode) in list4: # convert enteredCode to integer
code_check = 1
else:
code_check = 2
show_result()