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,它 必须 成为循环套件本身的一部分(因此嵌套在 whilefor 语句)。 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 循环也会退出是的。