一旦线程函数完成,在主线程中调用一个函数
Call a function in main thread once threaded function is completed
我正在构建一个 Tkinter GUI,我有一个过程需要一段时间才能完成,所以我将它线程化以防止 GUI 挂起。让我们调用线程函数 foo
。 foo
完成后,我需要调用另一个函数 bar
。 bar
需要从主线程调用(它使用了在线程内部不起作用的 matplotlib 方法)。
我似乎想不出我该怎么做。我考虑过加入线程,但这只会导致 GUI 挂起。我还考虑过使用一个信号变量,我会在 foo
的最后一行中更改它来告诉程序的其余部分它已完成以及执行时间 bar
,但后来我做不到弄清楚我如何在不挂起 GUI 的情况下在主线程中连续检查该变量。有什么想法吗?
使用Python3.7
可以使用threading.Event()
对象通知主线程,使用after()
定期调用一个函数来检查Event()
对象来决定什么时候调用bar()
.
下面是一个简单的例子:
import tkinter as tk
import threading
import time
def foo(event):
print('foo started')
time.sleep(5)
print('foo done')
# notify main thread
event.set()
def bar():
print('hello')
def check_event(event, callback):
print('.', end='')
if event.is_set():
# thread task is completed
callback()
else:
# check again 100 ms (adjust this to suit your case) later
root.after(100, check_event, event, callback)
root = tk.Tk()
# create the `Event()` object
event = threading.Event()
# start the checking
check_event(event, bar)
# start the thread task
threading.Thread(target=foo, args=(event,)).start()
root.mainloop()
我正在构建一个 Tkinter GUI,我有一个过程需要一段时间才能完成,所以我将它线程化以防止 GUI 挂起。让我们调用线程函数 foo
。 foo
完成后,我需要调用另一个函数 bar
。 bar
需要从主线程调用(它使用了在线程内部不起作用的 matplotlib 方法)。
我似乎想不出我该怎么做。我考虑过加入线程,但这只会导致 GUI 挂起。我还考虑过使用一个信号变量,我会在 foo
的最后一行中更改它来告诉程序的其余部分它已完成以及执行时间 bar
,但后来我做不到弄清楚我如何在不挂起 GUI 的情况下在主线程中连续检查该变量。有什么想法吗?
使用Python3.7
可以使用threading.Event()
对象通知主线程,使用after()
定期调用一个函数来检查Event()
对象来决定什么时候调用bar()
.
下面是一个简单的例子:
import tkinter as tk
import threading
import time
def foo(event):
print('foo started')
time.sleep(5)
print('foo done')
# notify main thread
event.set()
def bar():
print('hello')
def check_event(event, callback):
print('.', end='')
if event.is_set():
# thread task is completed
callback()
else:
# check again 100 ms (adjust this to suit your case) later
root.after(100, check_event, event, callback)
root = tk.Tk()
# create the `Event()` object
event = threading.Event()
# start the checking
check_event(event, bar)
# start the thread task
threading.Thread(target=foo, args=(event,)).start()
root.mainloop()