繁体   English   中英

在Python中使用Pyglet和Tkinter播放音乐

[英]Playing music with Pyglet and Tkinter in Python

我想用播放和停止按钮创建一个简单的GUI,以python播放mp3文件。 我使用Tkinter创建了一个非常简单的GUI,它由2个按钮(停止和播放)组成。

我创建了一个执行以下操作的函数:

def playsound () :
    sound = pyglet.media.load('music.mp3')
    sound.play()
    pyglet.app.run()

我将该功能作为命令添加到按钮播放中。 我还做了其他功能来停止音乐:

def stopsound ():
    pyglet.app.exit

我将此功能作为命令添加到第二个按钮。 但是问题是,当我打play时,python和gui冻结了。 我可以尝试关闭窗口,但它不会关闭,并且停止按钮没有响应。 我知道这是因为pyglet.app.run()一直执行到歌曲结束,但是我如何才能防止这种情况发生? 我想让gui在单击按钮时停止播放音乐。 关于在哪里可以找到解决方案的任何想法?

您正在将两个UI库混合在一起-本质上不是很糟糕,但是存在一些问题。 值得注意的是,它们两个都需要自己的主循环来处理事件。 TKinter使用它与桌面事件和用户生成的事件进行通信,在这种情况下,pyglet使用它来播放音乐。

这些循环中的每一个都会阻止正常的“自上而下”的程序流,就像我们在学习非GUI编程时所习惯的那样,该程序应基本上从主循环进行回调。 在这种情况下,在Tkinter回调的中间,将pyglet主循环(调用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线程上进行一次回调-此回调检查某些全局变量的状态,并根据它们选择停止音乐,更改正在播放的文件等等。上。

我会做类似的事情:

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()

此解决方案是最简单的一种:

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()

来源: http//ubuntuforums.org/showthread.php?t = 1651906

pyglet文档中有一个媒体播放器实现:

http://www.pyglet.org/doc/programming_guide/playing_sounds_and_music.html

您应该查看的脚本是media_player.py

希望这会帮助您入门

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM