1

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

我正在使用 Text Widget 来显示正在复制的文件的运行日志。基本上我在调用我的复制函数之前重新定向了标准输出,并且我正在使用“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 小部件中的文本大小是否有限制?我应该在我的代码中查看什么来解决这个挂起问题。

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

更新:(工作解决方案)

如果我使用update方法而不是update_idletasks. 现在我的问题是为什么它不能与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()
     self.widget.see('end')
     self.widget.configure(state="disabled")
4

1 回答 1

1

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

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

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

于 2012-09-11T11:56:27.613 回答