实现用Tkinter制作的秒表按钮释放功能

huangapple go评论53阅读模式
英文:

Implementing button release for a stopwatch with Tkinter

问题

这是您提供的代码的中文翻译部分:

class StopWatch(tk.Frame):
    def __init__(self, parent=None, **kw):
        tk.Frame.__init__(self, parent, kw)
        self._start = 0.0
        self._elapsedtime = 0.0
        self._running = 0

        self._timer_text = tk.StringVar()
        self._timer_text.set("00:00:00")
        self._canvas_color = tk.StringVar()
        self._canvas_color.set("yellow")
        self.grid(sticky=tk.NSEW)

        self.timer_label = tk.Label(self, textvariable=self._timer_text, font=("Helvetica", 48))
        self.timer_label.grid(row=0, column=1, pady=10, padx=10)

        self.canvas = tk.Canvas(self, width=100, height=100, bg="yellow", highlightthickness=0)
        self.canvas.grid(row=0, column=0, pady=10, padx=10)

        GPIO.add_event_detect(14, GPIO.FALLING, callback=self.start, bouncetime=50)
        GPIO.add_event_detect(15, GPIO.FALLING, callback=self.reset, bouncetime=50)
        GPIO.add_event_detect(21, GPIO.FALLING, callback=self.pause, bouncetime=200)

    def _update(self):
        """更新计时器标签以显示经过的时间."""
        self._elapsedtime = time.time() - self._start
        self._timer_text.set(time.strftime('%H:%M:%S', time.gmtime(self._elapsedtime)))
        if self._elapsedtime > 15:
            self.canvas.config(bg='red')

        if self._running:
            self.after(100, self._update)

    def start(self, channel):
        """开始计时器."""
        self._start = time.time() - self._elapsedtime
        self._running = 1
        self.canvas.config(bg='green')
        self._update()

    def pause(self, channel):
        """暂停计时器."""
        self._running = 0
        self.canvas.config(bg='orange')
        eStop_flag = True

        while eStop_flag == True:
            print("Stop flag True")
            time.sleep(0.2)
            if GPIO.input(21) != GPIO.LOW:
                print("Emergency Stop")
                time.sleep(0.5)
                eStop_resume = False
                while eStop_resume == False:
                    if GPIO.input(21) != GPIO.HIGH:
                        print("Released")
                        eStop_resume == True
                        time.sleep(1)
            eStop_flag == False
        self.start(channel)

    def reset(self, channel):
        """重置计时器."""
        self._start = time.time()
        self._elapsedtime = 0.0
        self._timer_text.set("00:00:00")
        self._running = 0
        self.canvas.config(bg='yellow')


if __name__ == '__main__':
    root = tk.Tk()
    root.title('Stopwatch')
    root.geometry('500x200')
    stopwatch = StopWatch(root)
    stopwatch.pack(expand=True, fill=tk.BOTH)
    root.mainloop()

请注意,我已经将代码中的HTML实体转换为相应的文本。如果您有任何进一步的问题或需要进一步的帮助,请告诉我。

英文:

I have designed a program that allows three buttons to control a stopwatch:

  • Start button, starts the timer: Canvas turns green (in progress), if timer reaches 15 seconds canvas will turn red.
  • Stop button, resets the timer: Canvas turns yellow (idle).
  • Emergency Stop button: When pressed, pauses timer (canvas turns orange). When released, resumes timer (canvas turns green).

Currently the Start & Stop buttons work fine. But the Emergency Stop (pause & resume) is where I am having issues.

If I start the timer say for 5 seconds and then press the Emergency Stop button to pause the timer, the timer does pause, but releasing the button causes the program to loop in the section that prints "Release" and doesn't restart the timer.

I am expecting the release of the Emergency Stop button to resume the timer turning the canvas green if below 15 seconds.

I am having struggle debugging the program as once in a tkinter loop you can't really see what buttons are being selected and where you are going with the program.

Here is the code I have written for this:

class StopWatch(tk.Frame):
def __init__(self, parent=None, **kw):
tk.Frame.__init__(self, parent, kw)
self._start = 0.0
self._elapsedtime = 0.0
self._running = 0
self._timer_text = tk.StringVar()
self._timer_text.set("00:00:00")
self._canvas_color = tk.StringVar()
self._canvas_color.set("yellow")
self.grid(sticky=tk.NSEW)
self.timer_label = tk.Label(self, textvariable=self._timer_text, font=("Helvetica", 48))
self.timer_label.grid(row=0, column=1, pady=10, padx=10)
self.canvas = tk.Canvas(self, width=100, height=100, bg="yellow", highlightthickness=0)
self.canvas.grid(row=0, column=0, pady=10, padx=10
GPIO.add_event_detect(14, GPIO.FALLING, callback=self.start, bouncetime=50)
GPIO.add_event_detect(15, GPIO.FALLING, callback=self.reset, bouncetime=50)
GPIO.add_event_detect(21, GPIO.FALLING, callback=self.pause, bouncetime=200)
def _update(self):
"""Update the timer label with elapsed time."""
self._elapsedtime = time.time() - self._start
self._timer_text.set(time.strftime('%H:%M:%S', time.gmtime(self._elapsedtime)))
if self._elapsedtime > 15:
self.canvas.config(bg='red')
if self._running:
self.after(100, self._update)
def start(self, channel):
"""Start the stopwatch."""
self._start = time.time() - self._elapsedtime
self._running = 1
self.canvas.config(bg='green')
self._update()
def pause(self, channel):
"""Pause the stopwatch."""
self._running = 0
self.canvas.config(bg='orange')
eStop_flag = True
while eStop_flag == True:
print("Stop flag True")
time.sleep(0.2)
if GPIO.input(21) != GPIO.LOW:
print("Emergency Stop")
time.sleep(0.5)
eStop_resume = False
while eStop_resume == False:
if GPIO.input(21) != GPIO.HIGH:
print("Released")
eStop_resume == True
time.sleep(1)
eStop_flag == False
self.start(channel)
def reset(self, channel):
"""Reset the stopwatch."""
self._start = time.time()
self._elapsedtime = 0.0
self._timer_text.set("00:00:00")
self._running = 0
self.canvas.config(bg='yellow')
if __name__ == '__main__':
root = tk.Tk()
root.title('Stopwatch')
root.geometry('500x200')
stopwatch = StopWatch(root)
stopwatch.pack(expand=True, fill=tk.BOTH)
root.mainloop()

答案1

得分: 1

In the pause function you are using double equals instead of a single one. It should look like this:

def pause(self, channel):
    """Pause the stopwatch."""
    self._running = 0
    self.canvas.config(bg='orange')
    e_stop_flag = True                # Variables should be lowercase

    while e_stop_flag:                # This is a Boolean variable, so you don't need a conditional statement
        print("Stop flag True")
        time.sleep(0.2)
        if GPIO.input(21) != GPIO.LOW:
            print("Emergency Stop")
            time.sleep(0.5)
            e_stop_resume = False
            while not e_stop_resume:    # Same here (but use "not")
                if GPIO.input(21) != GPIO.HIGH:
                    print("Released")
                    e_stop_resume = True  # this should set the var so use = 
                    time.sleep(1)
        e_stop_flag = False               # Same here
    self.start(channel)

(Note: GPIO refers to General Purpose Input/Output, typically used in Raspberry Pi and similar devices for controlling hardware.)

英文:

In the pause function you are using double equals instead of a single one. It should look like this:

def pause(self, channel):
"""Pause the stopwatch."""
self._running = 0
self.canvas.config(bg='orange')
e_stop_flag = True                # Variables should be lowercase
while e_stop_flag:                # This is a Boolean variable, so you don't  
# need a conditional statement
print("Stop flag True")
time.sleep(0.2)
if GPIO.input(21) != GPIO.LOW:
print("Emergency Stop")
time.sleep(0.5)
e_stop_resume = False
while not e_stop_resume:    # Same here (but use "not")
if GPIO.input(21) != GPIO.HIGH:
print("Released")
e_stop_resume = True  # this should set the var so use = 
time.sleep(1)
e_stop_flag = False               # Same here
self.start(channel)

(I don't know what GPIO is)

huangapple
  • 本文由 发表于 2023年4月17日 18:06:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76033973.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定