在Python中使用Pyglet和Tkinter播放音乐 [英] Playing music with Pyglet and Tkinter in Python

查看:361
本文介绍了在Python中使用Pyglet和Tkinter播放音乐的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I wanted to create a simple gui with a play and stop button to play an mp3 file in python. I created a very simple gui using Tkinter that consists of 2 buttons (stop and play).

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

I created a function that does the following:

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

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

I added that function as a command to the button play. I also made a different function to stop music:

def stopsound ():
    pyglet.app.exit

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

I added this function as a command to the second button. But the problem is that when I hit play, python and the gui freeze. I can try to close the window but it does not close, and the stop button is not responsive. I understand that this is because the pyglet.app.run() is executing till the song is over but how exactly do I prevent this? I want the gui to stop the music when I click on the button. Any ideas on where I can find a solution to this?

推荐答案

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

You are mixing two UI libraries together - that is not intrinsically bad, but there are some problems. Notably, both of them need a main loop of their own to process their events. TKinter uses it to communicate with the desktop and user-generated events, and in this case, pyglet uses it to play your music.

每个循环都会阻止正常的自顶向下"程序流,就像我们在学习非GUI编程时所习惯的那样,该程序应基本上从主循环进行回调.在这种情况下,在Tkinter回调的中间,将pyglet主循环(调用pyglet.app.run)置于运动中,控件将永远不会返回Tkinter库.

Each of these loops prevents a normal "top down" program flow, as we are used to when we learn non-GUI programming, and the program should proceed basically with callbacks from the main loops. In this case, in the middle of a Tkinter callback, you put the pyglet mainloop (calling pyglet.app.run) in motion, and the control never returns to the Tkinter library.

有时,不同库的循环可以在同一进程中共存,没有冲突-但是,您当然可以运行其中一个,也可以运行另一个.如果是这样,则有可能在不同的Python线程中运行每个库的mainloop.

Sometimes loops of different libraries can coexist on the same process, with no conflicts -- but of course you will be either running one of them or the other. If so, it may be possible to run each library's mainloop in a different Python thread.

如果它们不能一起存在,则必须以不同的方式处理每个库.

If they can not exist together, you will have to deal with each library in a different process.

因此,使音乐播放器在另一个线程中启动的一种方法可能是:

So, one way to make the music player to start in another thread could be:

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线程上进行一次回调-此回调检查某些全局变量的状态,并根据它们选择停止音乐,更改正在播放的文件等.上.

If Tkinter and pyglet can coexist, that should be enough to get your music to start. To be able to control it, however, you will need to implement a couple more things. My suggestion is to have a callback on the pyglet thread that is called by pyglet every second or so -- this callback checks the state of some global variables, and based on them chooses to stop the music, change the file being played, and so on.

这篇关于在Python中使用Pyglet和Tkinter播放音乐的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆