如果使用update_idletasks而不是更新,则Tkinter窗口挂起

时间:2012-09-11 11:40:42

标签: python tkinter

我开发了一个应用程序来复制磁盘上的文件并在Tkinter GUI中显示其进度。它使用自定义的shutil模块来复制文件。如果我直接使用我的自定义复制功能(没有GUI)来复制文件,那么它会正确复制所有文件并显示正在复制的文件的消息(已使用print语句进行复制)。现在的问题是当我使用GUI执行相同的操作时,它会在一段时间后挂起。

我正在使用Text Widget来显示正在复制的文件的运行日志。基本上我在调用我的复制功能之前重新指示了stdout,我使用“update_idletasks”来更新GUI。

class TextRedirector(object):
    def __init__(self, widget, tag="stdout"):
        self.widget = widget
        self.tag = tag

    def write(self, str):
         self.widget.configure(state="normal")
         self.widget.insert("end", str, (self.tag,))
         self.widget.update_idletasks()
         self.widget.see('end')
         self.widget.configure(state="disabled")

查询1:文本小部件中的文本大小是否有限制?我应该在代码中查看这个问题。

Query2:我注意到一旦调用了copy函数,我就无法使用“Minimize”按钮,只有在此操作结束后我才能使用它。在我的情况下,我需要复制大量数据,所以我想最小化应用程序并继续我的其他工作。

更新:

如果我使用“update”方法而不是“update_idletasks”,我的两个查询都会得到解决。现在我的问题是为什么它不适用于“update_idletasks”。据我所知,它还用于刷新GUI事件。

1 个答案:

答案 0 :(得分:1)

文本小部件中没有实际的大小限制。

如果没有看到你实际上是如何复制数据那么肯定不可能知道,但是你知道Tkinter是单线程的吗?如果您的命令需要很长时间,GUI将挂起,直到该操作完成。这是因为所有GUI操作都是通过响应事件发生的,并且当任何单个命令运行时,事件循环无法响应事件。

解决方法是在线程或单独的进程中运行长时间运行的操作。或者,您可以重构该函数,以便在事件循环的每次迭代中完成小块工作。请注意,如果使用线程,则无法直接从此其他线程写入GUI小部件。您必须使用线程安全队列在线程之间发送数据。