最近我开始偶尔使用tkwait,发现某些功能只在特定条件下起作用。例如:
import tkinter as tk
def w(seconds):
dummy = tk.Toplevel(root)
dummy.title(seconds)
dummy.after(seconds*1000, lambda x=dummy: x.destroy())
dummy.wait_window(dummy)
print(seconds)
root = tk.Tk()
for i in [5,2,10]:
w(i)
root.mainloop()
上面的代码完全正常,符合预期:
- for循环调用函数
- 函数运行并阻塞x秒钟的代码
- 窗口被销毁后,for循环继续执行
但在更多的事件驱动环境中,这些 tkwait
调用会变得棘手。文档中引用了以下说明:
如果事件处理程序再次调用 tkwait,则嵌套调用 tkwait 必须完成后,外部调用才能完成。
与 >>5
>>2
>>10
的输出不同,你会得到 >>10
>>2
>>5
,因为嵌套调用会阻塞内部调用,而外部调用会阻塞内部调用。我怀疑一个嵌套的 事件循环 或类似于 mainloop 的 正常方式处理事件。
使用此功能是否有问题?因为如果你仔细思考一下,几乎所有的 tkinter 对话框窗口都在使用此功能,而我之前从未读到过这种行为。
一个事件驱动的示例可能是:
import tkinter as tk
def w(seconds):
dummy = tk.Toplevel(root)
dummy.title(seconds)
dummy.after(seconds*1000, lambda x=dummy: x.destroy())
dummy.wait_window(dummy)
print(seconds)
root = tk.Tk()
btn1 = tk.Button(
root, command=lambda : w(5), text = '5 seconds')
btn2 = tk.Button(
root, command=lambda : w(2), text = '2 seconds')
btn3 = tk.Button(
root, command=lambda : w(10), text = '10 seconds')
btn1.pack()
btn2.pack()
btn3.pack()
root.mainloop()
使用
wait_something
存在另一个问题,如果wait_something
从未释放,它将阻止您的进程结束。