繁体   English   中英

如果使用update_idletasks而不是update,则Tkinter窗口将挂起

[英]Tkinter window got hung if update_idletasks is used instead of update

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

我正在使用文本小部件来显示正在复制的文件的运行日志。 基本上,在调用复制函数之前,我已经重定向了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:我已经注意到,一旦调用了复制功能,我将无法使用“最小化”按钮,只有在此操作结束后才能使用它。 就我而言,我需要复制大量数据,因此我想最小化该应用程序并继续进行其他工作。

更新:

如果我使用“ update”方法而不是“ update_idletasks”,则将解决我的两个查询。 现在我的问题是为什么它不能与“ update_idletasks”一起使用。 据我所知,它还用于刷新GUI事件。

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

没有看到您实际上是如何复制数据的,就不可能确定,但​​是您是否知道Tkinter是单线程的? 如果您的命令花费很长时间,则GUI将挂起,直到该操作完成。 这是因为所有GUI操作都是通过响应事件发生的,并且在运行任何单独的命令时,事件循环都无法响应事件。

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

暂无
暂无

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

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