Multithreading PythonTkinter:如何使用“加载”加载状态栏;“正在进行的工作”;调用在不同线程中运行的另一个函数之前

Multithreading PythonTkinter:如何使用“加载”加载状态栏;“正在进行的工作”;调用在不同线程中运行的另一个函数之前,multithreading,python-3.x,tkinter,Multithreading,Python 3.x,Tkinter,我对python真的很陌生。在我下面的程序中,我想在调用mywork函数之前将状态栏中的状态更新为“正在工作”。但只要我点击按钮,GUI就会冻结,我无法看到“正在工作”的状态。我想在单击按钮后立即查看“正在工作”状态 from tkinter import * import threading import time def check2(): global status while status=="continue": print("**** Wor

我对python真的很陌生。在我下面的程序中,我想在调用mywork函数之前将状态栏中的状态更新为“正在工作”。但只要我点击按钮,GUI就会冻结,我无法看到“正在工作”的状态。我想在单击按钮后立即查看“正在工作”状态

from tkinter import *
import threading
import time

def check2():    
    global status
    while status=="continue":
        print("**** Working in Progres ...")
        time.sleep(3)
    print("***** Work is Completed *****")
    statusbar["text"] = "Work is Completed"

def mywork():

    global status
    global t
    for i in range(3):
        print(i)
        time.sleep(2)
        print('Hello')
    status = "stop"


def on_click():

    global status
    status = "continue"
    statusbar["text"] = "Work in Progress"
    t = threading.Thread(target=mywork)
    statusbar["text"] = "Work in Progress"
    t.start()
    check2()
    t.join()


window=Tk()

b16 = Button(window,text='Disconnect',command=on_click)

b16.grid(row=0,column=0,padx=10, pady=10)

b16.config(height='1',width='15')

statusbar = Label(window,text="IDLE",bd=3,relief=SUNKEN,font='Helvetica 9 bold')

statusbar.grid(row=3,column=0,columnspan=4,rowspan=2)

statusbar.config(width="80",anchor="w")


window.mainloop()

有更好的方法可以做到这一点,但本质上的问题是on_click()函数在t.join()完成之前不会完成。这会导致按钮阻塞GUI,直到线程完成。下面是一种修改解决方案的方法,以使其按预期工作

from tkinter import *
import threading
import time

def check2():
    global status

    while status=="continue":
        print("**** Working in Progres ...")
        time.sleep(3)
    print("***** Work is Completed *****")
    statusbar["text"] = "Work is Completed"

def mywork():
    global status
    global t
    for i in range(3):
        print(i)
        time.sleep(2)
        print('Hello')
    status = "stop"

def on_click():
    global status
    status = "continue"
    statusbar["text"] = "Work in Progress"
    t = threading.Thread(target=mywork)
    statusbar["text"] = "Work in Progress"
    # Schedule the start of the thread outside of the on_click event.
    statusbar.after(10, lambda: start_thread(t))

def start_thread(t):
    t.start()
    check2()
    t.join()

window=Tk()
b16 = Button(window,text='Disconnect',command=on_click)
b16.grid(row=0,column=0,padx=10, pady=10)
b16.config(height='1',width='15')
statusbar = Label(window,text="IDLE",bd=3,relief=SUNKEN,font='Helvetica 9 bold')
statusbar.grid(row=3,column=0,columnspan=4,rowspan=2)
statusbar.config(width="80",anchor="w")
window.mainloop()

请修改代码的格式。非常感谢您的回答。。在这种情况下效果很好。但是如果函数mywork()需要在后端完成一项非常耗时的任务,而不是像大写那样只打印值,那么窗口仍然会冻结。sry我对多线程的理解非常简单,但我相信只有在调用time.sleep()时,对另一个函数check()的控制才会传递?我这样假设对吗?因此,如果函数在调用sleep之前有大任务要执行,那么。。。它不会再挂了吗?