首页 > 解决方案 > 如何在按键后删除标签

问题描述

我试图在玩家按下任意键后移除标签。但是,Python shell 会显示一条错误消息。我该如何解决?

我试过label.destroy()了,但是由于我已经有一个调用这个函数的标签,所以这个函数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()

我希望这个程序会删除名为 的标签any_key,但在我按下一个键之前它甚至没有出现。此外,Tkinter 显示了一个错误TypeError: place_configure() takes from 1 to 2 positional arguments but 3 were given,即使我只给出了 2 个用于放置any_key标签的参数。如果您注释掉any_key.place(),则会出现另一个错误,内容如下:

Traceback (most recent call last):
  File "Python37\lib\tkinter\__init__.py", line 1705, in __call__
    return self.func(*args)
  File "Python\Python37\lib\tkinter\__init__.py", line 749, in callit
    func(*args)
  File "Python\Python37\Programs\Tests\test 8.py", line 22, in countdown
    label['text'] = count
  File "Python\Python37\lib\tkinter\__init__.py", line 1492, in __setitem__
    self.configure({key: value})
  File "Python\Python37\lib\tkinter\__init__.py", line 1485, in configure
    return self._configure('configure', cnf, kw)
  File "Python\Python37\lib\tkinter\__init__.py", line 1476, in _configure
    self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: invalid command name ".!canvas.!label2"

如何修复这些错误?

标签: pythonpython-3.xtkinterlabelruntime-error

解决方案


在我在评论中描述的更改之后,我得到了工作代码

place需要带名称的参数place(x=..., y=...)

root.pack()将不起作用 -root没有方法pack()。你不能把 window 放在 windowroot里面root

我也使用count > 0代替,count > -1现在它可以检查count == 0

from tkinter import *

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 > 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()"

root = Tk()

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

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

root.bind_all('<Key>', testing)
#root.pack() # you try to put window `root` inside window `root`

root.mainloop()

因为您可以在倒计时结束之前销毁标签,testing()所以最好通知countdown小部件不存在。我会用label = None这个

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

推荐阅读