Python 如何在按键后删除标签

Python 如何在按键后删除标签,python,python-3.x,tkinter,label,runtime-error,Python,Python 3.x,Tkinter,Label,Runtime Error,我试图在玩家按下任何键后移除标签。但是,pythonshell会显示一条错误消息。我该如何解决这个问题 我尝试过label.destroy,但由于我已经有了调用此函数的label,label.destroy函数无法工作 from tkinter import * root = Tk() def testing(event): print("You have pressed a key.") root.unbind_all('<Key>')

我试图在玩家按下任何键后移除标签。但是,pythonshell会显示一条错误消息。我该如何解决这个问题

我尝试过label.destroy,但由于我已经有了调用此函数的label,label.destroy函数无法工作

from tkinter import *

root = Tk()

def testing(event):
    print("You have pressed a key.")
    root.unbind_all('<Key>')
    label.destroy() # There are two of these.

def countdown(count, label):
    label['text'] = count
    if count > -1:
        root.after(1000, countdown, count-1, label)
    elif count == 0:
        label['text'] = 'Time \nExpired'
    elif count < 0:
        label.destroy() # The second "label.destroy()"

# any_key = root.create_text(250, 400, anchor=CENTER, font=('Calibri', 20), text='Press any key to start.')
# I commented the previous line out because that was my previous code.

any_key = Label(root, anchor=CENTER, font=('Calibri', 20), text='Press any key to start.')
any_key.place(250, 400) # Error 2

root.bind('<Key>', testing)
label = Label(root, anchor=CENTER, font=('Calibri', 48))
label.place(x=50, y=100)
countdown(10, label)

root.bind_all('<Key>', testing)

root.pack()
root.mainloop()

如何修复这些错误?

在我在注释中描述的更改之后,我会得到工作代码

place需要名为placex=…,y=

root.pack将不起作用-root没有方法包。不能将窗口根放在窗口根中

我还使用count>0而不是count>-1,现在它可以检查count==0


要解决错误2,应执行以下操作:

any_key.place(x=250, y=400) # SOLVE ERROR
我还有一个错误:root.pack,因为它应该是label.pack

执行两次销毁,因为有两行root.bind,testing和root.bind\u all,testing只保留一行

控制台中发生错误是因为测试和倒计时两种方法是异步的,所以倒计时在测试之前开始,并在销毁后尝试在标签上执行某些操作。 因此,您需要同步此方法,并与label==null共享标签的状态

from tkinter import *
import threading
import functools

root = Tk()
state = True

def synchronized(wrapped):
    lock = threading.Lock()
    @functools.wraps(wrapped)
    def _wrap(*args, **kwargs):
        print("Calling '%s' with Lock %s" % (wrapped.__name__, id(lock)))
        with lock:
            return wrapped(*args, **kwargs)
    return _wrap

@synchronized
def testing(event):
    global state
    print(event)
    print("You have pressed a key.")
    root.unbind_all('<Key>')
    state = False
    label.destroy() # There are two of these.

@synchronized
def countdown(count, label):
    global state
    print(count)
    print(state)
    if state: 
        label['text'] = count
        if count > 0:
            root.after(1000, countdown, count-1, label)
        elif count == 0:
            label['text'] = 'Time \nExpired'
        elif count < 0:
            label.destroy() # The second "label.destroy()"

# any_key = root.create_text(250, 400, anchor=CENTER, font=('Calibri', 20), text='Press any key to start.')
# I commented the previous line out because that was my previous code.

any_key = Label(root, anchor=CENTER, font=('Calibri', 20), text='Press any key to start.')
any_key.place(x=250, y=400) # SOLVE ERROR

root.bind('<Key>', testing)
label = Label(root, anchor=CENTER, font=('Calibri', 48))
label.place(x=50, y=100)
countdown(10, label)



label.pack() # SOLVE ERROR
root.mainloop()

始终显示有问题的完整错误消息-完整回溯。有很多有用的信息。不要期望我们运行代码来查看errorplace期望参数的名称,就像代码标签的另一行一样。placex=50,y=100当count为零时,如果count>-1,它就会执行,如果count==0,则不会。您没有创建root-ie.root=tk.tk-因此它在我的计算机上不起作用。您不能执行root.pack,因为它毫无意义-您不能将窗口放在同一个窗口或任何其他窗口中。我刚刚测试了您的代码。当我按下一个键时,它会删除倒计时标签,而不是任意键标签。然后使用任意键。销毁而不是标签。销毁其他两个模块是python内置的吗?它太复杂了。@我知道,但会考虑所有可能的并发situation@18ballz是的,它们进入默认库
def testing(event):
    global label

    print("You have pressed a key.")

    root.unbind_all('<Key>')

    if label is not None:
         label.destroy() # There are two of these.
         label = None


def countdown(count, label):
    global label

    if label is not None:
        label['text'] = count
        if count > 0: # not -1
            root.after(1000, countdown, count-1, label)
        elif count == 0:
            label['text'] = 'Time \nExpired'
            # to destroy after 1s
            root.after(1000, countdown, count-1, label)
        elif count < 0:
            label.destroy() # The second "label.destroy()"
            label = None
any_key.place(x=250, y=400) # SOLVE ERROR
from tkinter import *
import threading
import functools

root = Tk()
state = True

def synchronized(wrapped):
    lock = threading.Lock()
    @functools.wraps(wrapped)
    def _wrap(*args, **kwargs):
        print("Calling '%s' with Lock %s" % (wrapped.__name__, id(lock)))
        with lock:
            return wrapped(*args, **kwargs)
    return _wrap

@synchronized
def testing(event):
    global state
    print(event)
    print("You have pressed a key.")
    root.unbind_all('<Key>')
    state = False
    label.destroy() # There are two of these.

@synchronized
def countdown(count, label):
    global state
    print(count)
    print(state)
    if state: 
        label['text'] = count
        if count > 0:
            root.after(1000, countdown, count-1, label)
        elif count == 0:
            label['text'] = 'Time \nExpired'
        elif count < 0:
            label.destroy() # The second "label.destroy()"

# any_key = root.create_text(250, 400, anchor=CENTER, font=('Calibri', 20), text='Press any key to start.')
# I commented the previous line out because that was my previous code.

any_key = Label(root, anchor=CENTER, font=('Calibri', 20), text='Press any key to start.')
any_key.place(x=250, y=400) # SOLVE ERROR

root.bind('<Key>', testing)
label = Label(root, anchor=CENTER, font=('Calibri', 48))
label.place(x=50, y=100)
countdown(10, label)



label.pack() # SOLVE ERROR
root.mainloop()