为什么在移动Tkinter-GUI时工作线程会冻结?

时间:2014-07-23 14:58:39

标签: python multithreading python-3.x tkinter freeze

我在Python 3.3中有一个Tkinter-GUI,带有一个进度条和一个启动另一个线程的按钮。此线程在10秒内填充进度条,并在此期间在控制台上打印0到99之间的数字 只要我没有移动或调整GUI窗口的大小,它就可以正常工作。如果我删除标记的行progress.step(1),以便工作线程不会触及进度条,因此根本不会影响GUI,它会在控制台上连续打印数字如果我操纵窗户。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from tkinter import *
import tkinter.ttk as ttk
import _thread
import time

root = Tk()

def start():
    _thread.start_new_thread(thread, ())

def thread():
    for i in range(0, 100):
        time.sleep(0.1)
        progress.step(1)     #<-----
        print(i)

progress = ttk.Progressbar()
progress.pack()
button = Button(root, text="Start", command=start)
button.pack()

root.mainloop()

为什么会发生这种情况以及通常通过GUI操作来避免工作线程中断?

提前致谢!

1 个答案:

答案 0 :(得分:2)

IIRC,那取决于窗口管理器。移动/调整窗口大小时,有些会锁定窗口(以及所有子项,包括进度条)。

像KDE这样的新窗口管理器允许程序在操作窗口时继续渲染到窗口中。

[编辑] 大多数UI框架都不是线程安全的。 Python中使用的UI框架有时是免除的,因为Python具有GIL,这确保只有一个线程可以更改全局状态(即窗口小部件属性)。

如何在Tkinter中使用多个线程有几个相关的问题:

简而言之,您不应该在线程中执行任何与UI相关的工作。而是将事件发送到mainloop