使用After后,Tkinter在等待回调时冻结

时间:2017-05-22 16:02:20

标签: python python-3.x tkinter

我正在尝试使用Tkinter 构建一个小的 Python GUI应用程序。打开应用程序时会打开一个主窗口。然后可以单击按钮打开新的顶层。在这个顶层,有一个计时器(倒计时),按下按钮时开始。

我的问题是,当计时器倒计时,顶层会冻结。我可能错过了关于Tkinter如何工作(以及如何构造代码)的基本知识。我希望您可以澄清为什么代码没有按预期工作。

from tkinter import *

class Application:def __init__(self, master=NONE):
    self.root = Tk()

    btnTimer = Button(self.root, text="Open timer", command=self.open_timer)
    btnTimer.grid(row=1, column=0)

    self.root.mainloop()

def open_timer(self):
    # Hide main window
    self.root.withdraw()  # Hide main window

    # Make window for controls
    self.wdowControl = Toplevel(self.root)

    # Timer
    self.wdowControl.timerText = Label(self.wdowControl, text="00:00:00", font=("Helvetica", 80))
    self.wdowControl.timerText.grid(row=0, column=0)

    btnStart = Button(self.wdowControl, text="Start timer", command=self.start_timer)
    btnStart.grid(row=1, column=0)

def start_timer(self):
    self.update_timer(5) # Timer in seconds

def update_timer(self, t):
    if t > 0:
        m, s = divmod(t, 60)
        h, m = divmod(m, 60)

        timeLeft = "%d:%02d:%02d" % (h, m, s)
        self.wdowControl.timerText.configure(text=timeLeft)
        t -= 1
        self.wdowControl.after(1000, self.update_timer(t)) 
    else:
        self.wdowControl.timerText.configure(text="00:00:00", fg='red')

app = Application())

注意: 我昨天开始使用Python进行编码,我可能没有开始学习我应该先学习的基本知识。但是,嘿,这就是让我开心的原因。 :)

1 个答案:

答案 0 :(得分:1)

在以下行中使用after后;

"engines": {
  "node": ">=6.9.5 <7.0.0",
  "npm": ">=3.10.7 <4.0.0",
  "yarn": ">=0.21.3 <0.22.0"
}

该功能正在被立即调用。这意味着你的程序会冻结,因为它只是一次又一次地调用它。

要使用self.wdowControl.after(1000, self.update_timer(t)) 在这种情况下传递变量,请在函数名后面使用另一个逗号指定它。因此,要修复程序,您需要更改我提到的行:

after

希望这有帮助!