如何在按下H键后立即终止winsound播放任务?
问题解决:按下H键立即停止闹钟音效
问题原因
你的代码里winsound.PlaySound()默认是阻塞调用,一旦开始播放就会直到音效结束才返回,所以即使按下H键修改了alarm_flag,当前的播放也会继续完成才会退出循环。另外,keyboard.is_pressed的循环检测效率很低,还会占用不必要的CPU资源。
解决方案
- 给
PlaySound添加winsound.SND_ASYNC参数,让音效异步播放,调用后立即返回,这样可以随时中断播放。 - 按下H键时,不仅设置
alarm_flag,还要调用winsound.PlaySound(None, winsound.SND_PURGE)直接终止当前播放。 - 用
keyboard.add_hotkey替代循环检测按键,更高效且代码更简洁。 - 设置线程为守护线程,确保主程序退出时所有线程自动结束。
修改后的代码
import winsound from threading import Thread import keyboard import sys alarm_flag = True def alarm(): global alarm_flag while alarm_flag: # 异步播放音效,调用后立即返回 winsound.PlaySound("C:\\windows\\media\\Alarm01.wav", winsound.SND_FILENAME | winsound.SND_ASYNC) def stop_alarm(): global alarm_flag def on_h_press(): nonlocal alarm_flag alarm_flag = False # 立即停止当前播放的音效 winsound.PlaySound(None, winsound.SND_PURGE) # 退出整个程序 sys.exit() # 注册H键的热键回调 keyboard.add_hotkey('h', on_h_press) # 保持线程运行,监听按键 keyboard.wait() # 设置守护线程,主程序退出时线程自动结束 alarm_thread = Thread(target=alarm, daemon=True) stop_alarm_thread = Thread(target=stop_alarm, daemon=True) alarm_thread.start() stop_alarm_thread.start() # 让主程序等待,否则会直接退出 stop_alarm_thread.join()
关键说明
winsound.SND_ASYNC:让播放操作在后台进行,函数调用后立即返回,不会阻塞线程。winsound.SND_PURGE:用于清除当前正在播放的音效,实现立即停止的效果。keyboard.add_hotkey:相比循环检测,这种方式更高效,只有当按键按下时才会触发回调。- 守护线程:设置
daemon=True,确保主程序退出时,所有子线程也会自动终止,避免残留进程。
内容的提问来源于stack exchange,提问作者ParsaTheH
相关产品推荐
相关产品推荐

