0

在使用mixer.music.load() 加载.mp3 文件之前,一切正常。之后,我创建的窗口上的按钮仍然响应,但窗口本身没有响应。我无法拖动窗口,也无法使用 x 按钮关闭窗口。它们不会突出显示,就好像您可以在加载音乐后完全按下它们一样。我知道主循环仍在运行,因为当鼠标按应有的方式与它们碰撞时,我的按钮会突出显示。我只是不知道为什么窗口本身没有响应。

奇怪的是我有一个加载按钮,它打开一个 tkinter 文件对话框来获取一个目录,如果我点击它并关闭文件对话框,pygame 主窗口会像往常一样再次响应。

import os
import pygame as pg
import tkinter.filedialog
import tkinter
from pygame import mixer

pg.init()
WIDTH, HEIGHT = 500, 800
HW = WIDTH // 2
HH = HEIGHT // 2
win = pg.display.set_mode((WIDTH, HEIGHT))
pg.display.set_caption("Music Player")
CLOCK = pg.time.Clock()

# Colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)


def play_song(directory, song_list):
    mixer.init()
    mixer.music.load(os.path.join(directory, song_list[0]))
    pg.mixer.music.play()


def get_files(directory):
    file_list = []
    for entry in os.listdir(directory):
        file = os.path.join(directory, entry)
        ext = os.path.splitext(entry)[-1].lower()
        if os.path.isfile(file) and ext == '.mp3':  # adds only files, that are .mp3
            file_list.append(entry)
    return file_list


def get_directory():
    tkinter.Tk().withdraw()  # Without this a blank tkinter window will appear.
    try:
        directory = tkinter.filedialog.askdirectory()  # This opens the file browser.
        files_list = get_files(directory)
        return directory, files_list
    except FileNotFoundError:
        return 0, []


class Button(object):
    def __init__(self, pic, hover, click, x, y):
        self.pic = pic
        self.hover = hover
        self.click = click
        self.x = x
        self.y = y
        self.w = self.pic.get_width()
        self.h = self.pic.get_height()
        self.hw = self.w // 2
        self.hh = self.h // 2

    def collide(self, mouse_x, mouse_y):
        if mouse_x > self.x and mouse_x < self.x + self.w:
            if mouse_y > self.y and mouse_y < self.y + self.h:
                return True

    def draw(self, win1, clicked=False):
        mouse_pos = pg.mouse.get_pos()
        if clicked:
            win1.blit(self.click, (self.x, self.y))
        elif self.collide(mouse_pos[0], mouse_pos[1]):
            win1.blit(self.hover, (self.x, self.y))
        else:
            win1.blit(self.pic, (self.x, self.y))


play_idle = pg.image.load('play.png')
play_hover = pg.image.load('play_hover.png')
play_click = pg.image.load('play_click.png')
play = Button(play_idle, play_hover, play_click, HW - 52, HEIGHT - 152)

pause_idle = pg.image.load('pause.png')
pause_hover = pg.image.load('pause_hover.png')
pause_click = pg.image.load('pause_click.png')
pause = Button(pause_idle, pause_hover, pause_click, HW - 52, HEIGHT - 152)

skip_idle = pg.image.load('skip.png')
skip_hover = pg.image.load('skip_hover.png')
skip_click = pg.image.load('skip_click.png')
skip = Button(skip_idle, skip_hover, skip_click, WIDTH - 152, HEIGHT - 152)

load_idle = pg.image.load('load.png')
load_hover = pg.image.load('load_hover.png')
load_click = pg.image.load('load_click.png')
load = Button(load_idle, load_hover, load_click, 50, 50)


def draw(win, clicked_play, clicked_load, playing):
    win.fill(WHITE)
    if playing:
        pause.draw(win, clicked_play)
    else:
        play.draw(win, clicked_play)
    skip.draw(win)
    load.draw(win, clicked_load)
    pg.display.update()


def main():
    directory, song_list = '', []
    CLOCK.tick(60)
    run = True
    while run:
        clicked_play = False
        clicked_load = False
        loaded = False
        playing = mixer.music.get_busy()
        events = pg.event.get()
        for event in events:
            if event.type == pg.QUIT:
                run = False
            if event.type == pg.MOUSEBUTTONDOWN:
                print('button down')
                if event.button == 1:
                    mouse_pos = pg.mouse.get_pos()
                    if load.collide(mouse_pos[0], mouse_pos[1]):
                        # Pause music
                        clicked_load = True
                        draw(win, clicked_play, clicked_load, playing)
                        directory, song_list = get_directory()
                    if play.collide(mouse_pos[0], mouse_pos[1]) and not playing:
                        clicked_play = True
                        if len(song_list) > 0:
                            play_song(directory, song_list)
                            print('playing')
                    if pause.collide(mouse_pos[0], mouse_pos[1]) and playing:
                        clicked_play = False
                        pg.mixer.music.stop()
                        print('pause')

        draw(win, clicked_play, clicked_load, playing)

    pg.display.quit()
    pg.quit()


main()
4

1 回答 1

0

我找到了解决方案。这是一个线程问题。感谢@stovfl 为我指明了正确的方向。

with concurrent.futures.ThreadPoolExecutor() as executor:
    future = executor.submit(get_directory)
    return_value = future.result()

get_directory 是一个使用 tkinter 的函数。

于 2020-05-13T00:44:52.153 回答