繁体   English   中英

"Python Tkinter 从主线程 VS 新线程更改 UI"

[英]Python Tkinter changing UI from the main thread VS new thread

在我学习 python 的过程中,我遇到了一个典型的冻结问题,即主线程被长时间运行的函数阻塞。 我找到的解决方案基本上是开始一个新线程。 我最终有两种方法似乎可以正常工作,但我很想知道我的理解是否正确。

我认为 pb.destory() 的第一种方式是从非主线程更新 UI 的示例

# --- functions ---
def longFunction():
    for i in range(10):
        print(i)
        time.sleep(0.25)
    # I believe this is updating the UI from the non-main thread (remove the progress bar)
    pb.destroy()
    
        
def createNewThread():
    # I am expecting the prgoressbar animation to not get blocked/freeze.
    pb.start(10)
    pb.pack()
    
    thread = threading.Thread(target=longFunction)
    thread.daemon = True
    thread.start()

root = tk.Tk()
pb = Progressbar(root,mode='indeterminate') 
tk.Button(root,text='START', command=createNewThread).pack()

root.mainloop()

第二种方式,我基本上尝试将 after() 与我定期检查的标志一起使用。 我相信在这个 UI 更新发生在主线程中

# --- functions ---
def longFunction():
    for i in range(10):
        print(i)
        time.sleep(0.25)
    global isDone
    isDone = True

# Check on isDone flag every 100 ms 
def checkFlag():
    global isDone
    if isDone:
        # I believe this is updating the UI from the main thread (remove the progress bar)
        pb.destroy()
    else:
        root.after(100,checkFlag)
         
def createNewThread():
    # I am expecting the prgoressbar animation to not get blocked/freeze.
    pb.start(10)
    pb.pack()
    
    thread = threading.Thread(target=longFunction)
    thread.daemon = True
    thread.start()
    
    root.after(100,checkFlag)

# flag
isDone = False
root = tk.Tk()
pb = Progressbar(root,mode='indeterminate') 
tk.Button(root,text='START', command=createNewThread).pack()

root.mainloop()

我的问题是:

1-我的假设是否正确,第一种方法是从非主线程更新 UI,第二种方法是从主线程更新 UI?

2- 从非主线程更新 UI 是否存在问题(我知道在 WPF/C# 中它会导致太多问题)

3-有更好的解决方案吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM