如何停止播放播放声音模块中的声音



我正在制作一个计时器程序,我希望它在计时器结束时播放一首歌,但我也希望在按下按钮时停止声音。

我看到过其他帖子使用多处理模块(如何使用播放声音模块停止音频?(来停止音频,但我已经在使用线程模块,所以我想知道是否可以使用它来停止音频。

编辑:马蒂斯给出了一个不同于我想要的解决方案,但它仍然完美。glory9211也给出了我稍后在上寻找的解决方案

from tkinter import *
from time import sleep
from threading import Thread
from threading import Event
import playsound
class App(Tk):
def __init__(self):
super().__init__()
self.title("Clock")
self.t_evt = Event()
self.frame2 = Frame(self)
self.timerStart = Button(self.frame2, text="Start", command=self.tt_Start)
self.timerStart.config(height=2, width=5)
self.timerStart.grid(row=1)
self.timerEnd = Button(self.frame2, text="End", command=self.timer_End)
self.timerEnd.config(height=2, width=5)
self.timerEnd.grid(row=2)

def tt_Start(self):
t = Thread(target=self.timer_Start)
t.setDaemon(True)
t.start()
def timer_Start(self):
self.t_evt.clear()
timer_seconds = int(self.timerS_Entry.get())
timer_minutes = int(self.timerM_Entry.get())
if timer_seconds > 59:
timer_seconds -= 60
timer_minutes += 1
while not self.t_evt.is_set():
print(f"Minutes: {timer_minutes}, Seconds: {timer_seconds}")
self.timerSeconds.config(text=timer_seconds)
self.timerMinutes.config(text=timer_minutes)
self.update()
time = (timer_minutes * 60) + timer_seconds
timer_seconds -= 1
sleep(1)
if time == 0:
break
if timer_seconds < 0:
timer_seconds = 59
timer_minutes -= 1
playsound.playsound('C:\Users\nonon\mp3\song.wav')
print("TIMER UP")
return
def timer_End(self):
self.t_evt.set()

这里有一些代码供您使用,如果您需要更多,请告诉我。

同样,当我按下结束按钮时,我希望能够停止playsound.playsound('C:\Users\nonon\mp3\song.wav')

简短回答

您可以使用线程Events而不是线程。或者切换到多处理并使用p.terminate()

长答案

您无法停止python线程。线程使用任何提供的函数。人们使用旗帜来实现这一点好消息:有什么方法可以杀死线程吗?


def thread_func():
while flag:
print("I'm running")
def run_button():
flag = True
t = threading.Thread(target=thread_func)
t.start()
def stop_button():
flag = False
# This will make the function exit

但在您的情况下,playsound函数不是一个循环函数,您可以在其中偷偷添加一个标志来停止该函数。你可以想象它是不确定的睡眠功能,即

def play_sound():
time.sleep(1000000) # Replacing with playsound.playsound

所以使用线程。Events((我们可以通过这个示例代码来实现这一点

import random
import signal
import threading
import time
exit_event = threading.Event()

def bg_thread():
for i in range(1, 30):
print(f'{i} of 30 iterations...')
if exit_event.wait(timeout=random.random()):
break
print(f'{i} iterations completed before exiting.')

def signal_handler(signum, frame):
exit_event.set() # same as setting the flag False

signal.signal(signal.SIGINT, signal_handler)
th = threading.Thread(target=bg_thread)
th.start()
th.join()

这种解决方案有效地为您提供了";可中断的";睡眠,因为如果在线程被困在wait((调用的中间时设置了事件,那么等待将立即返回。

请阅读此处的详细示例:https://blog.miguelgrinberg.com/post/how-to-kill-a-python-thread

最新更新