我正在尝试制作秒表。我已经做到了,但是我想随时暂停并继续时间。我已经尝试了一些东西,但是我不知道该怎么做。有人会向我解释如何做吗?
import time, tkinter
canvas=tkinter.Canvas(width=1900,height=1000,bg='white')
canvas.pack()
canvas.create_text(950,300,text=':',font='Arial 600')
def write(x_rec,y_rec,x_text,rep):
canvas.create_rectangle(x_rec,0,y_rec,750,outline='white',fill='white')
if rep<10:
canvas.create_text(x_text,400,text='0'+str(rep),font='Arial 600')
else:
canvas.create_text(x_text,400,text=str(rep),font='Arial 600')
def write_minutes(rep):
write(0,900,450,rep)
def write_seconds(rep):
write(1000,1900,1450,rep)
def time(num,remember):
while remember[0]<num:
remember[1]+=1
write_seconds(remember[1])
if remember[1]==60:
remember[0]+=1
remember[1]=0
write_seconds(remember[1])
write_minutes(remember[0])
canvas.update()
canvas.after(1000)
remember=[0,0]
num=1
write_seconds(remember[1])
write_minutes(remember[0])
time(5,remember)
答案 0 :(得分:4)
我无法找出一种干净的方法来修改您的代码以执行您想要的事情,因此决定将秒表作为一个类来实现,以使程序更加面向对象,并避免使用大量的全局变量变量。
我还没有对它进行彻底的测试,但是有足够的知识可以让您理解。还要注意,我将 Resume Button
更改为一个可以在其与 Pause Button
之间切换的选项。这种方法使得不必再添加Button
。
我注意到在更新显示时,越来越多的对象不断添加到Canvas
可能是潜在的问题。对于短期运行的StopWatch
实例,通常不会有问题,但对于长期运行的实例可能会引起问题。
为避免这种情况,我修改了代码以更新现有的相应Canvas
文本对象(如果有)。我也将Button
移到了StopWatch
上方的顶部。
import time
import tkinter as tk
from functools import partial
PAUSE, RESUME = 0, 1
# Button callback functions
def _toggle(callback):
toggle_btn.state = 1 - toggle_btn.state
toggle_btn.config(**toggle_btn_states[toggle_btn.state])
callback()
def _stop():
stopwatch.cancel_updates()
toggle_btn.config(state=tk.DISABLED)
stop_btn.config(state=tk.DISABLED)
class StopWatch:
def __init__(self, parent, run_time, width, height):
self.run_time = run_time
self.width, self.height = width, height
self.font = 'Arial 600'
self.canvas = tk.Canvas(parent, width=width, height=height, bg='white')
self.canvas.pack()
self.canvas.create_text(950, 300, text=':', font=self.font)
self.running, self.paused = False, False
self.after_id = None
def start(self):
self.elapsed_time = 0 # In seconds.
self._display_time()
self.after_id = self.canvas.after(1000, self._update)
self.running, self.paused = True, False
def _update(self):
if self.running and not self.paused:
if self.elapsed_time == self.run_time:
_stop() # Sets self.running to False.
self.canvas.bell() # Beep.
else:
self.elapsed_time += 1
self._display_time()
if self.running: # Keep update process going.
self.after_id = self.canvas.after(1000, self._update)
def _display_time(self):
mins, secs = divmod(self.elapsed_time, 60)
self._write_seconds(secs)
self._write_minutes(mins)
def _write_minutes(self, mins):
self._write(0, 900, 450, 'mins', mins)
def _write_seconds(self, secs):
self._write(1000, 1900, 1450, 'secs', secs)
def _write(self, x_rec, y_rec, x_text, tag, value):
text = '%02d' % value
# Update canvas text widget if it has non-empty text.
if self.canvas.itemcget(tag, 'text'):
self.canvas.itemconfigure(tag, text=text)
else: # Otherwise create it.
self.canvas.create_text(x_text, 400, text=text, tag=tag, font=self.font)
def pause_updates(self):
if self.running:
self.paused = True
def resume_updates(self):
if self.paused:
self.paused = False
def cancel_updates(self):
self.running, self.paused = False, False
if self.after_id:
self.canvas.after_cancel(self.after_id)
self.after_id = None
# main
root = tk.Tk()
# Create a Frame for Buttons (allows row of them to be centered).
button_frame = tk.Frame(root)
button_frame.pack(side=tk.TOP)
# Create StopWatch and configure buttons to use it.
stopwatch = StopWatch(root, 5, 1900, 1000)
toggle_btn = tk.Button(button_frame)
toggle_btn_states = {}
toggle_btn_states.update({
PAUSE: dict(
text='Pause', bg='red', fg='white',
command=partial(_toggle, stopwatch.pause_updates)),
RESUME: dict(
text='Resume', bg='green', fg='white',
command=partial(_toggle, stopwatch.resume_updates))
})
toggle_btn.state = PAUSE
toggle_btn.config(**toggle_btn_states[toggle_btn.state])
toggle_btn.pack(side=tk.LEFT, padx=2)
stop_btn = tk.Button(button_frame, text='Stop', bg='blue', fg='white', command=_stop)
stop_btn.pack(side=tk.LEFT, padx=2)
stopwatch.start()
root.mainloop()