python 使用 pygame-change 播放音频时无法中断 while 循环
python can't break while loop when play audio with pygame-change
我尝试了一些新的东西来适应代码。现在,当我按下 ctrl + s 时,音频真的停止了,但是当我的私人助理再次以相同的方式播放音乐时 运行,音乐并没有像第一次那样停止:
import glob
import os
import keyboard
os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = "hide"
import pygame
songs = glob.glob("C:\Users\zivsi\Music\*.mp3")
import random
song = random.choice(songs)
with open("song_choice.txt", "r") as file:
read = file.read()
if (read == song):
print("switch song")
song = random.choice(songs)
song_name = song.replace("C:\Users\zivsi\Music\", "").replace(".mp3", "")
print("song: ", song_name)
pygame.mixer.init()
music = pygame.mixer.music.load(song)
pygame.mixer.music.play()
while (pygame.mixer_music.get_busy()):
pygame.time.Clock().tick(10)
keyboard.add_hotkey("ctrl + s", lambda: pygame.mixer_music.stop())
#如果我按 ctrl + s,音乐会停止,但它只播放一次`
您不能在不同的范围内使用 break
,它 必须 成为循环套件本身的一部分(因此嵌套在 while
或 for
语句)。 A lambda
是一个函数,它是一个不同的作用域。
因为您想异步跳出循环,所以您需要一些其他方式从键盘回调处理程序返回主循环。在一般的计算机工程术语中,您需要某种 synchronization primitive 来同步同时发生的不同事物。
也就是说,你想设置某种标志,你可以在你的while
循环中检查,所以while pygame.mixer_music.get_busy() and not keyboard_ctrl_s_flag:
。您可以使用任何全局值执行此操作,可能 是安全的:
keyboard_ctrl_s_flag = False
def control_s_handler():
"""Called when the keyboard combination CTRL-S is pressed"""
global keyboard_ctrl_s_flag
keyboard_ctrl_s_flag = True
keyboard.add_hotkey("ctrl + s", control_s_handler)
然后您可以在循环中使用它:
# reset the flag to false, in case it was already set to true before
keyboard_ctrl_s_flag = False
while pygame.mixer_music.get_busy() and not keyboard_ctrl_s_flag:
pygame.time.Clock().tick(10)
我说这个可能是安全的,因为我不太确定PyGame是如何运行它的事件处理循环。鉴于您还在循环中使用了 pygame.time.Clock().tick(10)
让我认为事件循环可能会等待您的 Python 代码进行 return 控制,然后再做其他事情。
下次用户使用CTRL-S
时,调用control_s_handler()
回调,keyboard_ctrl_s_flag
设置为True
,当控制returns 到 while
循环(因为 pygame.time.Clock().tick(10)
return 控制了你的 Python 代码)即使 pygame.mixer_music.get_busy()
仍然存在,while
循环也会退出是的。
我尝试了一些新的东西来适应代码。现在,当我按下 ctrl + s 时,音频真的停止了,但是当我的私人助理再次以相同的方式播放音乐时 运行,音乐并没有像第一次那样停止:
import glob
import os
import keyboard
os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = "hide"
import pygame
songs = glob.glob("C:\Users\zivsi\Music\*.mp3")
import random
song = random.choice(songs)
with open("song_choice.txt", "r") as file:
read = file.read()
if (read == song):
print("switch song")
song = random.choice(songs)
song_name = song.replace("C:\Users\zivsi\Music\", "").replace(".mp3", "")
print("song: ", song_name)
pygame.mixer.init()
music = pygame.mixer.music.load(song)
pygame.mixer.music.play()
while (pygame.mixer_music.get_busy()):
pygame.time.Clock().tick(10)
keyboard.add_hotkey("ctrl + s", lambda: pygame.mixer_music.stop())
#如果我按 ctrl + s,音乐会停止,但它只播放一次`
您不能在不同的范围内使用 break
,它 必须 成为循环套件本身的一部分(因此嵌套在 while
或 for
语句)。 A lambda
是一个函数,它是一个不同的作用域。
因为您想异步跳出循环,所以您需要一些其他方式从键盘回调处理程序返回主循环。在一般的计算机工程术语中,您需要某种 synchronization primitive 来同步同时发生的不同事物。
也就是说,你想设置某种标志,你可以在你的while
循环中检查,所以while pygame.mixer_music.get_busy() and not keyboard_ctrl_s_flag:
。您可以使用任何全局值执行此操作,可能 是安全的:
keyboard_ctrl_s_flag = False
def control_s_handler():
"""Called when the keyboard combination CTRL-S is pressed"""
global keyboard_ctrl_s_flag
keyboard_ctrl_s_flag = True
keyboard.add_hotkey("ctrl + s", control_s_handler)
然后您可以在循环中使用它:
# reset the flag to false, in case it was already set to true before
keyboard_ctrl_s_flag = False
while pygame.mixer_music.get_busy() and not keyboard_ctrl_s_flag:
pygame.time.Clock().tick(10)
我说这个可能是安全的,因为我不太确定PyGame是如何运行它的事件处理循环。鉴于您还在循环中使用了 pygame.time.Clock().tick(10)
让我认为事件循环可能会等待您的 Python 代码进行 return 控制,然后再做其他事情。
下次用户使用CTRL-S
时,调用control_s_handler()
回调,keyboard_ctrl_s_flag
设置为True
,当控制returns 到 while
循环(因为 pygame.time.Clock().tick(10)
return 控制了你的 Python 代码)即使 pygame.mixer_music.get_busy()
仍然存在,while
循环也会退出是的。