You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派Python+Guizero:timer.repeat()计时归零时无法停止

解决Guizero倒计时结束后重复触发闹钟的问题

问题根源

你的代码里timer.repeat(1000, reduceTime)会每秒自动调用一次reduceTime函数,但计时归0后没有任何逻辑停止这个重复任务,导致start_alarm_1()被反复执行,闹钟持续触发。

解决方案

核心是在计时结束时,调用Guizero控件的cancel()方法终止重复任务,同时优化代码避免重复创建控件和任务:

修改后的完整代码

# 导入UI、GPIO和定时器模块
from guizero import App, Text, TextBox, PushButton, Box, Window
import RPi.GPIO as GPIO
import time
import datetime

# 全局变量声明
timer = None
timerbottom = None

# 按钮触发的启动计时函数
def startTimer():
    global timer, timerbottom
    # 处理输入逻辑
    if (set_time_input.value == "" and set_time_input_min.value == ""):
        currentTimeLeft = 3  # 输入为空时默认3秒
    else:
        if (set_time_input.value != "" and set_time_input_min.value == ""):
            currentTimeLeft = int(set_time_input.value)
        else:
            currentTimeLeft = int(set_time_input_min.value) * 60

    # 复用或创建倒计时文本控件
    if timer is not None:
        # 取消旧的定时任务,避免多个任务同时运行
        timer.cancel(reduceTime)
        timer.value = str(currentTimeLeft)
    else:
        timer = Text(timer_box, text=str(currentTimeLeft), size=30, color="red")
        timerbottom = Text(timer_box, text="\n Sekunden.")
    
    # 启动新的每秒重复任务
    timer.repeat(1000, reduceTime)

# 倒计时更新函数
def reduceTime():
    global timer
    if int(timer.value) > 0:
        timer.value = int(timer.value) - 1
    else:
        # 终止重复任务,停止后续调用
        timer.cancel(reduceTime)
        start_alarm_1()

# GPIO初始化
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.cleanup()

# 触发树莓派GPIO闹钟
def start_alarm_1():
    GPIO.setup(20, GPIO.OUT)
    GPIO.output(20, GPIO.LOW)
    time.sleep(3)
    GPIO.output(20, GPIO.HIGH)

# 初始化应用窗口
app = App(title="OSCE Timer", width=800, height=400)

# 输入区域
Text(app, text="Timer in seconds:")
set_time_input = TextBox(app)
Text(app, text="OR timer in Minutes:")
set_time_input_min = TextBox(app)
PushButton(app, command=startTimer, text="start Countdown")

# 倒计时显示区域
Text(app, text="Time:\n")
timer_box = Box(app)  # 补全原代码缺失的Box容器

# 启动应用
app.display()

关键修改说明

  1. 终止重复任务:在reduceTime的else分支中添加timer.cancel(reduceTime),直接取消每秒调用的任务,确保计时结束后不再执行后续逻辑。
  2. 复用控件与清理旧任务:在startTimer中检查是否已有timer控件,如果有则先取消旧的定时任务,再更新数值,避免多次点击按钮后界面出现多个倒计时文本,同时防止多个定时任务并行运行。
  3. 补全缺失控件:原代码中使用了timer_box但未创建,添加timer_box = Box(app)修复运行报错问题。

内容的提问来源于stack exchange,提问作者Oscar Donnerstag

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 11:02:07