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

Python / tkinter: How to stop all the current running threads? (not asking for exiting, just stopping)

我已经创建了一个示例代码,所以我可以更具体一些。实际代码要复杂得多,但我想要停止按钮的功能有点相似。 我想不通的代码将在第 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()对象:

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

以下是基于您的示例:

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()