【问题标题】:Entry.delete in Tkinter not clearingTkinter 中的 Entry.delete 未清除
【发布时间】:2021-01-05 12:28:10
【问题描述】:

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

【问题讨论】:

  • 太长了,我们无法检查。你能提供给我们minimal reproducible example
  • 建议您通过使用 IDE 中的断点或只是在它们旁边的打印语句来验证 Entry.delete 方法是否实际上正在运行。

标签: python tkinter tkinter-entry


【解决方案1】:

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

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

最后,list3 和list4 是整数列表,而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()

【讨论】:

    猜你喜欢
    • 2016-05-03
    • 1970-01-01
    • 2013-03-24
    • 1970-01-01
    • 1970-01-01
    • 2018-02-10
    • 2013-03-28
    • 2018-07-27
    • 1970-01-01
    相关资源
    最近更新 更多