我想创建一个带有播放和停止按钮的简单gui来播放python中的mp3文件。我使用Tkinter创建了一个非常简单的gui,它包含2个按钮(停止和播放)。
我创建了一个执行以下操作的函数:
def playsound () :
sound = pyglet.media.load('music.mp3')
sound.play()
pyglet.app.run()
我将该功能添加为按钮播放的命令。我还做了一个不同的功能来阻止音乐:
def stopsound ():
pyglet.app.exit
我将此功能作为命令添加到第二个按钮。但问题是,当我点击游戏时,python和gui会冻结。我可以尝试关闭窗口,但它没有关闭,停止按钮没有响应。我知道这是因为pyglet.app.run()正在执行,直到歌曲结束,但我究竟如何阻止这个?当我点击按钮时,我希望gui停止播放音乐。关于我可以在哪里找到解决方案的任何想法?
答案 0 :(得分:5)
您正在将两个UI库混合在一起 - 这本质上并不坏,但存在一些问题。值得注意的是,他们都需要自己的主循环来处理他们的事件。 TKinter使用它与桌面和用户生成的事件进行通信,在这种情况下,pyglet使用它来播放你的音乐。
这些循环中的每一个都会阻止正常的“自上而下”程序流,因为我们习惯于学习非GUI编程时,程序应该基本上从主循环中进行回调。在这种情况下,在Tkinter回调的中间,你将pyglet mainloop(调用pyglet.app.run
)置于运动状态,控件永远不会返回到Tkinter库。
有时,不同库的循环可以在同一个进程中共存,没有冲突 - 当然,您将运行其中一个或另一个。如果是这样,可以在不同的Python线程中运行每个库的mainloop。
如果它们不能一起存在,则必须在不同的过程中处理每个库。
因此,让音乐播放器在另一个线程中启动的一种方法可能是:
from threading import Thread
def real_playsound () :
sound = pyglet.media.load('music.mp3')
sound.play()
pyglet.app.run()
def playsound():
global player_thread
player_thread = Thread(target=real_playsound)
player_thread.start()
如果Tkinter和pyglet可以共存,这应该足以让你的音乐开始。 但是,为了能够控制它,您需要实现更多的东西。我的建议是每隔一秒左右在pyglet上调用pyglet线程回调 - 这个回调检查一些全局变量的状态,并根据它们选择停止音乐,更改正在播放的文件,等等上。
答案 1 :(得分:1)
pyglet文档中有一个媒体播放器实现:
http://www.pyglet.org/doc/programming_guide/playing_sounds_and_music.html
您应该查看的脚本是media_player.py
希望这会让你开始
答案 2 :(得分:1)
我会做类似的事情:
import pyglet
from pyglet.gl import *
class main (pyglet.window.Window):
def __init__ (self):
super(main, self).__init__(800, 600, fullscreen = False)
self.button_texture = pyglet.image.load('button.png')
self.button = pyglet.sprite.Sprite(self.button_texture)
self.sound = pyglet.media.load('music.mp3')
self.sound.play()
self.alive = 1
def on_draw(self):
self.render()
def on_close(self):
self.alive = 0
def on_mouse_press(self, x, y, button, modifiers):
if x > self.button.x and x < (self.button.x + self.button_texture.width):
if y > self.button.y and y < (self.button.y + self.button_texture.height):
self.alive = 0
def on_key_press(self, symbol, modifiers):
if symbol == 65307: # [ESC]
self.alive = 0
def render(self):
self.clear()
self.button.draw()
self.flip()
def run(self):
while self.alive == 1:
self.render()
# -----------> This is key <----------
# This is what replaces pyglet.app.run()
# but is required for the GUI to not freeze
#
event = self.dispatch_events()
x = main()
x.run()
答案 3 :(得分:1)
此解决方案是最简单的解决方案:
import pyglet
foo=pyglet.media.load("/data/Me/Music/Goo Goo Dolls/[1998] Dizzy Up The Girl/11 - Iris.mp3")
foo.play()
def exiter(dt):
pyglet.app.exit()
print "Song length is: %f" % foo.duration
# foo.duration is the song length
pyglet.clock.schedule_once(exiter, foo.duration)
pyglet.app.run()