2012-09-11 55 views
0

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

我正在使用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:Text小部件中的文字大小是否有限制?我应该看看我的代码来解决这个挂起问题。查询2:我注意到,一旦复制函数被调用,我不能使用“最小化”按钮,我只能在该操作结束后使用它。在我的情况下,我需要复制大量数据,所以我想尽量减少应用程序并继续我的其他工作。

UPDATE:

我的查询两者都如果我使用 “更新” 的方法,而不是 “update_idletasks” 解决。现在我的问题是为什么它不适用于“update_idletasks”。据我所知,它也被用来刷新GUI事件。

回答

1

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

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

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

+0

Well函数,我称之为从磁盘复制文件,所以它可能需要时间(取决于数据大小,但我的数据已被分割成大小不超过15 MB的小文件)。这就是为什么我使用更新idletasks在复制一个文件后更新GUI。我注意到,在复制几个文件后,它会停止响应,并在一段时间后显示剩余的文件状态(到那时所有其他文件都被复制) – sarbjit

+0

请您指出一些线程解决方案的参考(示例)吗? – sarbjit

+0

我的问题是固定的,如果我使用“更新”而不是“update_idletasks”。现在问题是为什么它不能使用update_idletasks和更新方法 – sarbjit