Python / tkinter:如何停止所有当前正在运行的线程? 不要求退出,只是停止

问题描述

我已经创建了示例代码,因此我可以更具体一些。实际代码要复杂得多,但是在功能上我想要停止按钮。 我不知道的代码将在第25行。

import threading
from tkinter import *
import time
import concurrent.futures

window = Tk()
window.geometry('400x300')

def main_fctn():
    for i in range(500):
        print(f'Counting {i}')
        time.sleep(2)


def count_threads():
    print(f'\n\nCurrently running threads: {threading.activeCount()}\n\n'.upper())


def starting_thread(arg=None):
    with concurrent.futures.ThreadPoolExecutor() as excecuter:
        thread_list = excecuter.submit(main_fctn)


def stop_threads():
    ### CODE TO STOP THE RUNNING THREADS
    pass


button1 = Button(window,text='Start Thread!')
button1.bind('<Button-1>',lambda j: threading.Thread(target=starting_thread).start())
button1.pack(pady=25)

button2 = Button(window,text='Stop Thread!')
button2.bind('<Button-1>',lambda j: threading.Thread(target=stop_threads).start())
button2.pack(pady=25)

button3 = Button(window,text='Count number of Threads')
button3.bind('<Button-1>',lambda j: threading.Thread(target=count_threads).start())
button3.pack(pady=25)

window.mainloop()

解决方法

简单的方法是使用threading.Event()对象:

  • 在全局空间中创建threading.Event()的实例
  • clear()内的for循环之前在对象上调用main_fctn()
  • 检查是否在for循环中使用is_set()设置了对象,如果已设置,则中断for循环
  • 如果您想停止线程,请
  • set()内部的对象上调用stop_threads()

以下是基于您的示例:

import threading
from tkinter import *
import time
import concurrent.futures

window = Tk()
window.geometry('400x300')

# event object for stopping thread
event_obj = threading.Event()

def main_fctn():
    event_obj.clear() # clear the state
    for i in range(500):
        if event_obj.is_set():
            # event object is set,break the for loop
            break
        print(f'Counting {i}')
        time.sleep(2)
    print('done')

def count_threads():
    print(f'\n\nCurrently running threads: {threading.activeCount()}\n\n'.upper())


def starting_thread(arg=None):
    with concurrent.futures.ThreadPoolExecutor() as excecuter:
        thread_list = excecuter.submit(main_fctn)


def stop_threads():
    ### CODE TO STOP THE RUNNING THREADS
    event_obj.set()


button1 = Button(window,text='Start Thread!')
button1.bind('<Button-1>',lambda j: threading.Thread(target=starting_thread).start())
button1.pack(pady=25)

button2 = Button(window,text='Stop Thread!')
button2.bind('<Button-1>',lambda j: threading.Thread(target=stop_threads).start())
button2.pack(pady=25)

button3 = Button(window,text='Count number of Threads')
button3.bind('<Button-1>',lambda j: threading.Thread(target=count_threads).start())
button3.pack(pady=25)

window.mainloop()