我试图在玩家按下任意键后删除标签。但是,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
的标签,但是在按下键之前它甚至没有显示出来。此外,即使我只给出了两个用于放置TypeError: place_configure() takes from 1 to 2 positional arguments but 3 were given
标签的参数,Tkinter也会显示一个显示any_key
的错误。如果您注释掉any_key.place()
,则会显示另一个错误,正在读取。 Tkinter回调中的异常
Traceback (most recent call last):
File "C:\Users\kevin\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)
File "C:\Users\kevin\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py", line 749, in callit
func(*args)
File "C:\Users\kevin\AppData\Local\Programs\Python\Python37\Programs\Tests\test 8.py", line 22, in countdown
label['text'] = count
File "C:\Users\kevin\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py", line 1492, in __setitem__
self.configure({key: value})
File "C:\Users\kevin\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py", line 1485, in configure
return self._configure('configure', cnf, kw)
File "C:\Users\kevin\AppData\Local\Programs\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"
如何解决这些错误?
答案 0 :(得分:2)
经过我在注释中描述的更改,我得到了工作代码
place
需要名称为place(x=..., y=...)
的参数
root.pack()
不起作用-root
没有方法pack()
。您不能将窗口root
放在窗口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
答案 1 :(得分:-1)
要解决错误2,您应该执行以下操作:
any_key.place(x=250, y=400) # SOLVE ERROR
我对此也有一个错误:“ root.pack()”,因为应该是“ label.pack()”
进行两次销毁,因为有两行“ root.bind('',测试)”和“ root.bind_all(”,测试)”仅保留其中一个。
控制台中发生错误是因为“测试”和“倒数”这两种方法是异步的,因此倒数在测试之前开始,并在销毁之后尝试在标签上做一些事情。 因此,您需要同步此方法并共享标签的状态(也使用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()