Python Tkinter:倒数计时器非常滞后且不准确
Python Tkinter: Countdown Timer is very laggy and not accurate
我在python中使用Tkinter制作了一个倒数计时器,但是非常,秒不是真正的秒(计时器比应该的快)。
tkinter 的 after()
函数并没有完全等待指定的时间量,所以我不能每次使用 after(1)
等待 1 毫秒就减去 1 毫秒,它不会'不准确。所以现在程序找到等待 1ms 时经过的确切时间 after(1)
然后从计时器中减去这个时间。
任何人都可以建议编辑或只是编辑我的程序来解决这些问题吗?
程序如下:
from tkinter import *
import time
import datetime
class root(Tk):
def __init__(self):
super(root, self).__init__()
self.title("Timer")
self.buttonplay = Button(self, text = "Play", fg= 'green', command = self.play)
self.buttonplay.pack()
self.buttonpause = Button(self, text = "Pause", fg = "red", command=self.pause)
self.buttonpause.pack()
self.buttonreset = Button(self, text = "Reset", fg = "red", command=self.reset)
self.buttonreset.pack()
self.createTimers()
def play(self):
self.timeit=True
self.timer1.configure(bg='#1C953D')
self.doTimer()
def pause(self):
self.timeit=False
self.timer1.configure(bg='#454545')
def reset(self):
self.timer1.destroy()
self.createTimers()
def createTimers(self):
self.total_minute = 1
self.total_second = 5
self.total_micros = 0
self.total = self.total_second + self.total_minute *60 + self.total_micros*0.000001
self.originalTime = datetime.datetime.now()
self.micros = self.originalTime.microsecond
self.seconds = self.originalTime.second
self.minutes = self.originalTime.minute
self.time1 = StringVar()
self.time1.set(str(self.total_minute).rjust(2, '0') + ':' + str(self.total_second).rjust(2, '0') +'.'+ str(self.total_micros)[0:3].rjust(3, '0'))
self.timer1 = Label(self, textvariable=self.time1, bg='#454545', fg='white', font ="Gadugi 40 bold")
self.timer1.pack()
self.timer1.configure(bg='#454545')
def doTimer(self):
if (self.total_second + self.total_minute *60 + self.total_micros*0.000001) >0: #Checks if the timer ended
if self.timeit:
self.nowTime = datetime.datetime.now()
self.toDim = self.nowTime.microsecond
while self.toDim > 0:
if self.micros > 0:
self.micros = self.micros -1
self.toDim = self.toDim -1
else:
if self.seconds > 0:
self.seconds = self.seconds -1
self.micros = 999999
else:
self.minutes = self.minutes -1
self.seconds = 59
self.DimTime = datetime.datetime(self.originalTime.year, self.originalTime.month, self.originalTime.day, self.originalTime.hour, self.minutes, self.seconds, self.micros)
self.waitMicros = self.originalTime - self.DimTime
self.total_micros = self.total_micros - self.waitMicros.microseconds
if self.total_micros <0:
self.total_second = self.total_second -1
self.total_micros = 999999
if self.total_second <0:
self.total_minute = self.total_minute -1
self.total_second = 59
self.time1.set(str(self.total_minute).rjust(2, '0') + ':' + str(self.total_second).rjust(2, '0') +'.'+ str(self.total_micros)[0:3].rjust(3, '0'))
self.after(1, self.doTimer)
else:
self.time1.set('00:00.000')
self.timer1.configure(bg='#FF0000')
self.after(3000, self.reset)
root = root()
root.mainloop()
def play(self):
self.timeit = True
self.timer1.configure(bg='#1C953D')
self.start_time = time.time()
self.total_start = self.seconds + self.minutes * 60 + self.micros * 0.000001
self.doTimer()
def pause(self):
self.timeit = False
self.timer1.configure(bg='#454545')
def reset(self):
self.timer1.destroy()
self.createTimers()
def createTimers(self):
self.start_time = time.time()
self.minutes = 1
self.seconds = 5
self.micros = 0
self.total_start = self.seconds + self.minutes * 60 + self.micros * 0.000001
self.time1 = StringVar()
self.time1.set(str(self.minutes).rjust(2, '0') + ':' + str(self.seconds).rjust(2, '0') + '.' + str(
self.micros)[0:3].rjust(3, '0'))
self.timer1 = Label(self, textvariable=self.time1, bg='#454545', fg='white', font="Gadugi 40 bold")
self.timer1.pack()
self.timer1.configure(bg='#454545')
def doTimer(self):
if (self.seconds + self.minutes * 60 + self.micros * 0.000001) > 0: # Checks if the timer ended
if self.timeit:
self.time_left = self.start_time - time.time() + self.total_start
self.minutes = int(self.time_left) // 60
self.seconds = int(self.time_left) % 60
self.micros = int((self.time_left - int(self.time_left)) * 1000000)
self.time1.set(
str(self.minutes).rjust(2, '0') + ':' + str(self.seconds).rjust(2, '0') + '.' + str(
self.micros)[0:3].rjust(3, '0'))
self.after(1, self.doTimer)
else:
self.time1.set('00:00.000')
self.timer1.configure(bg='#FF0000')
self.after(3000, self.reset)
我在python中使用Tkinter制作了一个倒数计时器,但是非常,秒不是真正的秒(计时器比应该的快)。
tkinter 的 after()
函数并没有完全等待指定的时间量,所以我不能每次使用 after(1)
等待 1 毫秒就减去 1 毫秒,它不会'不准确。所以现在程序找到等待 1ms 时经过的确切时间 after(1)
然后从计时器中减去这个时间。
任何人都可以建议编辑或只是编辑我的程序来解决这些问题吗?
程序如下:
from tkinter import *
import time
import datetime
class root(Tk):
def __init__(self):
super(root, self).__init__()
self.title("Timer")
self.buttonplay = Button(self, text = "Play", fg= 'green', command = self.play)
self.buttonplay.pack()
self.buttonpause = Button(self, text = "Pause", fg = "red", command=self.pause)
self.buttonpause.pack()
self.buttonreset = Button(self, text = "Reset", fg = "red", command=self.reset)
self.buttonreset.pack()
self.createTimers()
def play(self):
self.timeit=True
self.timer1.configure(bg='#1C953D')
self.doTimer()
def pause(self):
self.timeit=False
self.timer1.configure(bg='#454545')
def reset(self):
self.timer1.destroy()
self.createTimers()
def createTimers(self):
self.total_minute = 1
self.total_second = 5
self.total_micros = 0
self.total = self.total_second + self.total_minute *60 + self.total_micros*0.000001
self.originalTime = datetime.datetime.now()
self.micros = self.originalTime.microsecond
self.seconds = self.originalTime.second
self.minutes = self.originalTime.minute
self.time1 = StringVar()
self.time1.set(str(self.total_minute).rjust(2, '0') + ':' + str(self.total_second).rjust(2, '0') +'.'+ str(self.total_micros)[0:3].rjust(3, '0'))
self.timer1 = Label(self, textvariable=self.time1, bg='#454545', fg='white', font ="Gadugi 40 bold")
self.timer1.pack()
self.timer1.configure(bg='#454545')
def doTimer(self):
if (self.total_second + self.total_minute *60 + self.total_micros*0.000001) >0: #Checks if the timer ended
if self.timeit:
self.nowTime = datetime.datetime.now()
self.toDim = self.nowTime.microsecond
while self.toDim > 0:
if self.micros > 0:
self.micros = self.micros -1
self.toDim = self.toDim -1
else:
if self.seconds > 0:
self.seconds = self.seconds -1
self.micros = 999999
else:
self.minutes = self.minutes -1
self.seconds = 59
self.DimTime = datetime.datetime(self.originalTime.year, self.originalTime.month, self.originalTime.day, self.originalTime.hour, self.minutes, self.seconds, self.micros)
self.waitMicros = self.originalTime - self.DimTime
self.total_micros = self.total_micros - self.waitMicros.microseconds
if self.total_micros <0:
self.total_second = self.total_second -1
self.total_micros = 999999
if self.total_second <0:
self.total_minute = self.total_minute -1
self.total_second = 59
self.time1.set(str(self.total_minute).rjust(2, '0') + ':' + str(self.total_second).rjust(2, '0') +'.'+ str(self.total_micros)[0:3].rjust(3, '0'))
self.after(1, self.doTimer)
else:
self.time1.set('00:00.000')
self.timer1.configure(bg='#FF0000')
self.after(3000, self.reset)
root = root()
root.mainloop()
def play(self):
self.timeit = True
self.timer1.configure(bg='#1C953D')
self.start_time = time.time()
self.total_start = self.seconds + self.minutes * 60 + self.micros * 0.000001
self.doTimer()
def pause(self):
self.timeit = False
self.timer1.configure(bg='#454545')
def reset(self):
self.timer1.destroy()
self.createTimers()
def createTimers(self):
self.start_time = time.time()
self.minutes = 1
self.seconds = 5
self.micros = 0
self.total_start = self.seconds + self.minutes * 60 + self.micros * 0.000001
self.time1 = StringVar()
self.time1.set(str(self.minutes).rjust(2, '0') + ':' + str(self.seconds).rjust(2, '0') + '.' + str(
self.micros)[0:3].rjust(3, '0'))
self.timer1 = Label(self, textvariable=self.time1, bg='#454545', fg='white', font="Gadugi 40 bold")
self.timer1.pack()
self.timer1.configure(bg='#454545')
def doTimer(self):
if (self.seconds + self.minutes * 60 + self.micros * 0.000001) > 0: # Checks if the timer ended
if self.timeit:
self.time_left = self.start_time - time.time() + self.total_start
self.minutes = int(self.time_left) // 60
self.seconds = int(self.time_left) % 60
self.micros = int((self.time_left - int(self.time_left)) * 1000000)
self.time1.set(
str(self.minutes).rjust(2, '0') + ':' + str(self.seconds).rjust(2, '0') + '.' + str(
self.micros)[0:3].rjust(3, '0'))
self.after(1, self.doTimer)
else:
self.time1.set('00:00.000')
self.timer1.configure(bg='#FF0000')
self.after(3000, self.reset)