首页 > 解决方案 > Tkinter 中的 Entry.delete 未清除

问题描述

我尝试制作一个简单的数字检查器,显示数字是正确还是错误。在匆忙编写了一些原型代码之后,我无法清除这些字段。我挖掘了很多关于这个主题的问题,但找不到答案。我的尝试是show_result()

我究竟做错了什么?

它应该接受数字,并带有最后一个数字;核实。如果正确,则显示接受图像,否则显示拒绝图像并在错误输入后清除条目。并在 3 秒后删除图像。

我怀疑这个num_limit()函数搞砸了,但我不知道是什么。

所有其他文件都可以在这里找到: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()

标签: pythontkintertkinter-entry

解决方案


里面num_limit(),你应该检查的内容是否Entry为空,如果为空返回True。如果没有此验证,您将无法删除Entry空字符串不是有效输入的内容。

您还在验证函数返回之前调用code_checker()过,因此您将从Entry4内部获得空字符串code_checker()。用于after()安排code_checker()验证后的执行。

最后,list3andlist4是整数列表,但是enteredCode是字符串,所以检查结果总是 2。enteredCode在检查之前转换为整数。

以下是修改num_limit()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()

推荐阅读