def countdown():

全局 time, timer_ID

    timer_ID = display.after(1000, countdown)

    display.config(text=time)
    start.config(state="disabled")
    time += 1
    root.update()

def close():

    root.after_cancel(timer_ID)
    time.sleep(2)
    root.destroy()

在 tkinter 中,不能在主循环外执行任何 GUI 相关的操作。使用root.after_cancel()时,需要在 GUI 相关的操作(如root.update())之后执行它。如果你在其他地方(如你提到的使用time.sleep()函数)执行root.after-cancel(), tkinter 框架可能还没有更新主界面(因为time.sleep()`会暂停整个程序),所以你会收到错误"TclError: bad argument \"cancel\": invalid or incomplete command name"。

最合适的做法是将root.destroy()放到close()函数的末尾,当root.after_cancel()成功后立刻销毁 Tkinter 框架。