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()
我已经创建了一个示例代码,所以我可以更具体一些。实际代码要复杂得多,但我想要停止按钮的功能有点相似。 我想不通的代码将在第 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 中创建
- 在
main_fctn()
内的 for 循环之前对对象调用 - 检查是否在for循环中使用
is_set()
设置了对象,如果设置了,则中断for循环 - 如果要停止线程
stop_threads()
,请在stop_threads()
内的对象上调用set()
threading.Event()
的实例
clear()
以下是基于您的示例:
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()