Python Tkinter秒表错误

时间:2015-07-23 11:01:43

标签: python tkinter

我用python和tkinter制作了一个双倒计时器,但是如果tkinter窗口不在前台并且它不能同时运行,它似乎无法运行。这是我的代码:

import tkinter as tk
import tkinter.ttk as ttk
import time
class app:

 def __init__(self):
   self = 0

 def mainGUIArea():
    def count_down_1():
        for i in range(79, -1, -1):
            timeCount = "{:02d}:{:02d}".format(*divmod(i, 60))
            time_str.set(timeCount)
            root.update()
            time.sleep(1)

    def count_down_2():
        for j in range(10, -1, -1):
            timeCount = "{:02d}:{:02d}".format(*divmod(j, 60))
            time_str1.set(timeCount)
            root.update()
            time.sleep(1)

    #Main Window
    root = tk.Tk()
    root.title("Super Timer V1.0")
    root.minsize(300,300)
    root.geometry("500x300")

    #Timer1
    time_str = tk.StringVar()
    label_font = ('Courier New', 40)
    tk.Label(root, textvariable = time_str, font = label_font, bg = 'white', fg = 'blue', relief = 'raised', bd=3).pack(fill='x', padx=5, pady=5)
    tk.Button(root, text=' Start Timer! ',bg='lightgreen',fg='black', command=count_down_1).pack()
    tk.Button(root, text='Stop and Exit',bg='red',fg='white', command=root.destroy).pack()

    #Timer2
    time_str1 = tk.StringVar()
    label_font = ('Courier New', 40)
    tk.Label(root, textvariable = time_str1, font = label_font, bg = 'white', fg='blue', relief='raised', bd=3).pack(fill='x', padx=5, pady=5)
    tk.Button(root, text=' Start Timer! ',bg='lightblue',fg='black', command=count_down_2).pack()
    tk.Button(root, text='Stop and Exit',bg='red',fg='white', command=root.destroy).pack()


def main():
  app.mainGUIArea()

main()

你有什么建议吗?谢谢:)

2 个答案:

答案 0 :(得分:1)

time.sleep的调用至少是问题的一部分。当你打电话给睡眠时,确实会这样 - 它让应用程序进入睡眠状态。没有事件可以处理,GUI冻结。这是倒数计时器的错误方法。

另一个问题是在调用update的同时调用循环内的time.sleep。此调用将处理事件,这意味着当其中一个循环正在运行并且您单击一个按钮时,您可能最终调用另一个函数,交错两个循环。

定期执行某些操作的正确方法是使用after重复调用函数。一般模式是:

def update_display(self):
    <do whatever code you want to update the display>
    root.after(1000, self.update_display)

您可以将所需数量并行运行(显然达到实际限制),并且您的GUI将在更新之间完全响应。

这是一个简单的例子:

class Countdown(tk.Label):
    def __init__(self, parent):
        tk.Label.__init__(self, parent, width=5, text="00:00")
        self.value = 0
        self._job_id = None

    def tick(self):
        self.value -= 1
        text = "{:02d}:{:02d}".format(*divmod(self.value, 60))
        self.configure(text=text)
        if self.value > 0:
            self._job_id = self.after(1000, self.tick)

    def start(self, starting_value=60):
        if self._job_id is not None: return

        self.value = starting_value
        self.stop_requested = False
        self.after(1000, self.tick)

    def stop(self):
        self.after_cancel(self._job_id)
        self._job_id = None

答案 1 :(得分:1)

这是一款简单的tkinter(gui)秒表我制作完美。看看

__author__ = 'Surya'
from tkinter import *
import time
class StopWatch(Frame):
    def __init__(self, parent = None, ** kw):
        Frame.__init__(self, parent, kw)
        self._timeelapsed = 0.0
        self._start = 0.0
        self._run = 0
        self.timestr = StringVar()
        self.makeWidgets()
    def makeWidgets(self):
        l = Label(self, textvariable=self.timestr)
        self._setTime(self._timeelapsed)
        l.pack(fill=X, expand=NO, pady=2, padx=2)

    def _update(self):
        self._timeelapsed = time.time() - self._start
        self._setTime(self._timeelapsed)
        self._timer = self.after(50, self._update)

    def _setTime(self, elap):
        minutes = int(elap/60)
        seconds = int(elap - minutes*60.0)
        hseconds = int((elap - minutes*60.0 - seconds)*100)
        self.timestr.set('%02d:%02d:%02d' % (minutes, seconds, hseconds))

    def Start(self):
        if not self._run:
            self._start = time.time() - self._timeelapsed
            self._update()
            self._run = 1

    def Stop(self):
        if self._run:
            self.after_cancel(self._timer)
            self._timeelapsed = time.time() - self._start
            self._setTime(self._timeelapsed)
            self._run = 0

    def Reset(self):
        self._start = time.time()
        self._timeelapsed = 0.0
        self._setTime(self._timeelapsed)


def main():
    root = Tk()
    sw = StopWatch(root)
    sw.pack(side=TOP)
    Button(root, text='Start!', command=sw.Start).pack(side=LEFT)
    Button(root, text='Stop!', command=sw.Stop).pack(side=LEFT)
    Button(root, text='Reset!!!', command=sw.Reset).pack(side=LEFT)
    Button(root, text='Quit!!!', command=root.quit).pack(side=LEFT)

    root.mainloop()

if __name__ == '__main__':
        main()