Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何用Tkinter按钮打破无限循环?_Python_Loops_Tkinter_Interrupt_Python 2.x - Fatal编程技术网

Python 如何用Tkinter按钮打破无限循环?

Python 如何用Tkinter按钮打破无限循环?,python,loops,tkinter,interrupt,python-2.x,Python,Loops,Tkinter,Interrupt,Python 2.x,我在一个使用Tkinter作为UI的程序中工作。我正在编写一个代码来反复播放音频。我正在使用pygame.mixer.music()播放音频 在UI中,我创建了两个按钮(“开始”和“停止”)。我在开始按钮上附加了一个包含循环结构的方法,这样当按下开始按钮时,循环将被执行并开始重复播放音频。现在我不知道如何连接停止按钮。例如,当按下停止按钮时,控件应退出循环。我可以使用中断或其他类似的东西吗?我对中断的概念一无所知。要继续,请帮助我进行哪种中断,该中断的库是什么,等等。如果没有,请帮助我如何继续使

我在一个使用
Tkinter
作为UI的程序中工作。我正在编写一个代码来反复播放音频。我正在使用
pygame.mixer.music()
播放音频

在UI中,我创建了两个按钮(“开始”和“停止”)。我在开始按钮上附加了一个包含循环结构的方法,这样当按下开始按钮时,循环将被执行并开始重复播放音频。现在我不知道如何连接停止按钮。例如,当按下停止按钮时,控件应退出循环。我可以使用中断或其他类似的东西吗?我对中断的概念一无所知。要继续,请帮助我进行哪种中断,该中断的库是什么,等等。如果没有,请帮助我如何继续使用停止按钮

这是我的密码:

from pygame import *
from Tkinter import *
import time
root = Tk()
root.geometry("1000x200")
root.title("sampler")
m=1
n=1
mixer.init()
def play():

    while m==1:

        print 'playing'
        mixer.music.load('audio 1.mp3')
        mixer.music.play()
        time.sleep(n)

start = Button(root, text="play", command = play)
start.pack()
stop = Button(root, text="Stop")
stop.pack()
mainloop()

n
定义每个循环播放音频的时间。

您需要向按钮添加命令
stop=Button(root,text=“stop”,command=stop)

仅仅添加一个stop命令可能不起作用,因为无限循环的结构方式,在单击播放时无法与tkinter界面交互。尝试按以下方式重新构建您的程序:

from Tkinter import *
from pygame import *
import time
import threading

switch = True
root = Tk()
n = 1
mixer.init()
root.geometry("1000x200")
root.title("sampler")


def play():
    def run():
        while switch:
            print 'playing'
            mixer.music.load('audio 1.mp3')
            mixer.music.play()
            time.sleep(n)
            if not switch:
                break

    thread = threading.Thread(target=run)
    thread.start()


def switch_on():
    global switch
    switch = True
    play()


def switch_off():
    global switch
    switch = False


def kill():
    root.destroy()


onbutton = Button(root, text="Play", command=switch_on)
onbutton.pack()
offbutton = Button(root, text="Stop", command=switch_off)
offbutton.pack()
killbutton = Button(root, text="Kill", command=kill)
killbutton.pack()

root.mainloop()

通过这种方式,tkinter按钮在不同的线程上运行,因此当一个线程循环时,您仍然可以与另一个线程交互。

Python并不完全支持中断,最接近的可能是某种信号处理程序,它通过其库受支持。但是,它们可能无法与Tkinter(或
pygame
)一起很好地工作,因此我认为这不是一个好的方法,而且它们也不是真正必要的,因为您想要做的事情可以在Tkinter的
mainloop()
中处理

虽然它看起来有点复杂,但我建议实现它的方法是将大多数播放控制功能封装在一个Python
类中。这将减少全局变量的使用,这将使程序更易于调试和进一步开发(因为面向对象编程(又称as)有许多优点)

下面说明了我的意思。注意,我使用的是Python3,因此必须对代码进行一些额外的更改,以使其能够与该版本一起工作。我不确定,但是这个版本也应该在Python2中工作,除非您需要更改Tkinter模块的
import
,如图所示

from pygame import *
from tkinter import *  # Change to "from Tkinter import *" for Python 2.x.

class PlayController(object):
    def __init__(self, mixer, music_filename, polling_delay):
        self.mixer = mixer
        self.music_filename = music_filename
        self.polling_delay = polling_delay  # In milliseconds.
        self.playing = False

    def play(self):
        if self.playing:
            self.stop()
        self.mixer.music.load(self.music_filename)
        self.mixer.music.play(-1)  # -1 means to loop indefinitely.
        self.playing = True
        root.after(self.polling_delay, self.check_status)  # Start playing check.

    def stop(self):
        if self.playing:
            self.mixer.music.stop()
            self.playing = False

    def check_status(self):
        if self.playing:
            print('playing')
        root.after(self.polling_delay, self.check_status)  # Repeat after delay.

root = Tk()
root.geometry("1000x200")
root.title("Sampler")
mixer.init()

play_control = PlayController(mixer, 'tone.wav', 1000)
Button(root, text="Play", command=play_control.play).pack()
Button(root, text="Stop", command=play_control.stop).pack()

mainloop()

谢谢你的宝贵建议,现在你的建议解决了闲逛(没有回应)的问题。但是,当按下停止按钮时,循环仍然不会退出。使用kill按钮,系统关闭窗口,但进程仍在运行,直到我关闭外壳。有没有办法解决这个问题。谢谢你,伙计。这很好,但是在这里,每次循环重复音频时,我都需要重复打印一些消息。因此,像您所不支持的那样单独循环音频的方法不符合我的需要。感谢您花费宝贵的时间帮助medani:使用通用小部件方法
after()
,可以相对轻松地解决此问题。这里有一些关于如何使用它。我已经修改了我的答案,以展示如何使用它来做你想做的事情(我想)。兄弟,我查阅了after()方法的文档,但我无法理解它。你能给我一些使用该方法的示例程序吗。提前谢了。当然,这里有几个:和。它通常用于在
tkinter
中制作动画。基本思想是,在调用
mainloop()
的过程中,指定的函数将在指定的延迟后被调用……为了反复调用,该函数通常会在
之后再次调用
,以便该过程重复。如果我的答案(与修复)解决您的问题,请考虑接受它(即点击在它的顶部附近的复选标记)。看见