Python 在工作线程完成后从主线程更新Tkinter小部件

Python 在工作线程完成后从主线程更新Tkinter小部件,python,multithreading,python-2.7,tkinter,Python,Multithreading,Python 2.7,Tkinter,我需要在线程完成后更新GUI,并从主线程调用这个更新ui函数(比如软件中断?)。工作线程如何调用主线程中的函数 示例代码: def thread(): ...some long task update_ui() #But call this in main thread somehow def main(): start_new_thread(thread) ...other functionality def update_ui(): Tkinter

我需要在线程完成后更新GUI,并从主线程调用这个更新ui函数(比如软件中断?)。工作线程如何调用主线程中的函数

示例代码:

def thread():
    ...some long task
    update_ui() #But call this in main thread somehow

def main():
    start_new_thread(thread)
    ...other functionality

def update_ui():
    Tkinter_widget.update()
我尝试使用两个线程都可以访问的队列或任何标志,但我必须持续等待/轮询以检查值是否已更新,然后调用函数-这种等待会使UI无响应。e、 g

flag = True

def thread():
    ...some long task
    flag = False

def main():
    start_new_thread(thread)
    while(flag): sleep(1)
    update_ui()
    ...other functionality

您的代码似乎有些假设性。这里有一些实现了你所描述的目标。它创建三个标签并初始化它们的文本。然后它开始三个线程。每个线程在一段时间后更新与主线程中创建的标签关联的tkinter变量。现在,如果主线程真的需要进行更新,队列确实可以工作,但必须修改程序才能完成更新

import threading
import time
from tkinter import *
import queue
import sys

def createGUI(master, widget_var):
    for i in range(3):
        Label(master, textvariable=widget_var[i]).grid(row=i, column=0)
        widget_var[i].set("Thread " + str(i) + " started")

def sometask(thread_id, delay, queue):
    print("Delaying", delay)
    time.sleep(delay)
    tdict = {'id': thread_id, 'message': 'success'}
    # You can put simple strings/ints, whatever in the queue instead
    queue.put(tdict)
    return

def updateGUI(master, q, widget_var, td):
    if not q.empty():
        tdict = q.get()
        widget_var[tdict['id']].set("Thread " + str(tdict['id']) + " completed with status: " + tdict['message'])
        td.append(1)
    if len(td) == 3:
        print("All threads completed")
        master.after(1000, timedExit)
    else:
        master.after(100, lambda w=master,que=q,v=widget_var, tcount=td: updateGUI(w,que,v,td))

def timedExit():
    sys.exit()

root = Tk()
message_q = queue.Queue()

widget_var = []
threads_done = []
for i in range(3):
    v = StringVar()
    widget_var.append(v)
    t = threading.Thread(target=sometask, args=(i, 3 + i * 3, message_q))
    t.start()

createGUI(root, widget_var)
updateGUI(root,message_q, widget_var, threads_done)
root.mainloop()