如何通过正确的"停止"来中断线程/进程? Tkinter(Python)中的按钮?

时间:2015-09-22 11:42:29

标签: python multithreading tkinter

我想要一些关于制作某种"停止"的问题的基础知识。在我的情况下终止一系列哔哔声的按钮:

from tkinter import *
import winsound
from random import randint

class App(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()
        self.widgets()

    def widgets(self):
        self.beep = Button(self, text = "Beep", command = play_beep)
        self.beep.pack()
        self.stop = Button(self, text = "Stop", command = stop_beep)
        self.stop.pack()

go_on = True
def play_beep():
    count = 10
    while go_on == True and count != 0:
        winsound.Beep(randint(100, 2500), 200)
        count -= 1

def stop_beep():
    go_on = False

root = Tk()
app = App(root)
root.mainloop()

当我按下" Beep"按钮它会被卡住以及所有GUI,直到蜂鸣声结束。谁能告诉我如何解决它?

2 个答案:

答案 0 :(得分:0)

首先,您的问题与线程或进程无关。 Tkinter是单线程的。

如果要在tkinter程序中定期运行某些函数,则必须为事件循环提供处理事件的机会。典型的解决方案是这样做:

def play_beep(count=10):
    if go_on and count != 0:
        winsound.Beep(randint(100, 2500), 200)
        root.after(1000, play_beep, count=1)

这将导致蜂鸣声每秒(1000毫秒)播放十次。在每次调用之间,事件循环将有机会处理其他事件。

现在,如果您运行的代码需要很长时间,那么您将不得不在单独的线程或进程中运行该代码。我对winsound.Beep一无所知,所以我不知道是否有必要。

其次,为了能够中断它,你需要使go_on全局,否则你只需设置一个永远不会被使用的局部变量。

def stop_beek():
    global go_on
    go_on = False

答案 1 :(得分:0)

我不使用TKinter,但我相信按下按钮不会创建单独的线程或进程。您的按钮卡住的原因是因为您的play_beep循环阻止了您的GUI执行循环。所以我们使用线程。该线程与GUI同时执行,因此您基本上可以同时执行两项操作(侦听GUI事件并发出蜂鸣声)。

csv