使用tkinter按钮停止多个线程

问题描述

我试图使用一个按钮来停止我在for循环中创建的所有线程。有停止线程的方法吗?

这是我的代码

import threading
import time
from tkinter import *

tk= Tk()

class go(threading.Thread):

    def __init__(self,c):
        threading.Thread.__init__(self)
        self.c = c
    def run(self):
        while 1 == 1 :
            time.sleep(5)
            print('This is thread: '+str(self.c))


for count in range(10):
    thread = go(count)
    thread.start()

btn1 = Button(tk,text="Stop All",width=16,height=5)
btn1.grid(row=2,column=0)

tk.mainloop()

解决方法

您需要提供一个条件来退出run()方法中的while循环。通常使用threading.Event对象:

def __init__(self,c):
    ...
    self.stopped = threading.Event()

然后,您需要检查是否使用Event设置了Event.is_set()对象:

def run(self):
    while not self.stopped.is_set():
        ...

因此要终止线程,只需设置Event对象。您可以创建一个类方法来做到这一点:

def terminate(self):
    self.stopped.set()

以下是基于您的示例的修改示例:

import threading
import time
from tkinter import *

tk = Tk()

class go(threading.Thread):
    def __init__(self,c):
        threading.Thread.__init__(self)
        self.c = c
        self.stopped = threading.Event()

    def run(self):
        while not self.stopped.is_set():
            time.sleep(5)
            print(f'This is thread: {self.c}')
        print(f'thread {self.c} done')

    def terminate(self):
        self.stopped.set()


threads = []  # save the created threads
for count in range(10):
    thread = go(count)
    thread.start()
    threads.append(thread)

def stop_all():
    for thread in threads:
        thread.terminate()

btn1 = Button(tk,text="Stop All",width=16,height=5,command=stop_all)
btn1.grid(row=2,column=0)

tk.mainloop()