我正在使用TKinter用GUI编写程序,用户可以在其中单击按钮,然后开始一个新的过程来使用multiprocess.Process
执行工作。这是必要的,因此在完成工作时仍可以使用GUI,这可能需要几秒钟。
GUI上还有一个文本框,当事情发生时,在其中显示程序的状态。这通常很简单,每个函数调用一个add_text()
函数,该函数仅在文本框中打印文本。但是,在单独的过程中调用add_text()
时,文本不会最终出现在文本框中。
我已经考虑过使用Pipe
或Queue
,但这需要使用某种循环来检查进程是否返回了任何东西,这也会导致主界面(GUI )过程无法使用。是否有某种方法可以在一个进程中调用某个函数,而该进程又可以在另一个进程中起作用?
这是我正在尝试做的一个简单例子
import time
import multiprocessing as mp
import tkinter as tk
textbox = tk.Text()
def add_text(text):
# Insert text into textbox
textbox.insert(tk.END, text)
def worker():
x = 0
while x < 10:
add_text('Sleeping for {0} seconds'.format(x)
x += 1
time.sleep(1)
proc = mp.Process(target=worker)
# Usually happens on a button click
proc.start()
# GUI should still be usable here
答案 0 :(得分:1)
异步事物实际上需要循环。 您可以使用Tk.after()方法将函数附加到TkInter的循环中。
import Tkinter as tk
class App():
def __init__(self):
self.root = tk.Tk()
self.check_processes()
self.root.mainloop()
def check_processes(self):
if process_finished:
do_something()
else:
do_something_else()
self.after(1000, check_processes)
app=App()
答案 1 :(得分:0)
我最终通过使用TKinter的after()方法来执行multiprocessing.Pipe
循环。它按一定间隔循环,并检查管道以查看是否有来自线程的消息,如果有,则将其插入文本框。
import tkinter
import multiprocessing
def do_something(child_conn):
while True:
child_conn.send('Status text\n')
class Window:
def __init__(self):
self.root = tkinter.Tk()
self.textbox = tkinter.Text()
self.parent_conn, child_conn = multiprocessing.Pipe()
self.process = multiprocessing.Process(target=do_something, args=(child_conn,))
def start(self):
self.get_status_updates()
self.process.start()
self.root.mainloop()
def get_status_updates()
status = self.check_pipe()
if status:
self.textbox.add_text(status)
self.root.after(500, self.get_status_updates) # loop every 500ms
def check_pipe():
if self.parent_conn.poll():
status = self.parent_conn.recv()
return status
return None