简体   繁体   English

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

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

I have developed an App to copy files on disk and display its progress in Tkinter GUI. 我已经开发了一个应用程序,可以在磁盘上复制文件并在Tkinter GUI中显示其进度。 It uses customized shutil module for copying files. 它使用定制的shutil模块复制文件。 If I use my customized copy function directly (without GUI) to copy files, then it copy all the files properly and display message for file being copied (have used print statement for the being copied). 如果我直接使用自定义的复制功能(无GUI)复制文件,则它将正确复制所有文件并显示要复制文件的消息(已使用要复制的打印语句)。 Now the problem is when I use the GUI for performing same operation, it hung after some time. 现在的问题是,当我使用GUI执行相同的操作时,它在一段时间后挂起。

I am using Text Widget to display the running log of the files being copied. 我正在使用文本小部件来显示正在复制的文件的运行日志。 Basically I have re-directed the stdout before calling my copy function and I am using “update_idletasks” to update the 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")

Query 1: Is there any limit on the text size in Text widget? 查询1:“文本”小部件中的文本大小是否有限制? What should I look in my code to address this hang issue. 我应该在代码中寻找什么来解决此挂起问题。

Query2 : I have noticed that once the copy function is called, I am not able to use “Minimize” button, I can only use it once this operation is over. Query2:我已经注意到,一旦调用了复制功能,我将无法使用“最小化”按钮,只有在此操作结束后才能使用它。 In my case, I need to copy huge data, so I want to minimize the App and continue with my other work. 就我而言,我需要复制大量数据,因此我想最小化该应用程序并继续进行其他工作。

UPDATE: 更新:

Both of my queries are addressed if i use "update" method instead of "update_idletasks". 如果我使用“ update”方法而不是“ update_idletasks”,则将解决我的两个查询。 Now my question why it didn't worked with "update_idletasks". 现在我的问题是为什么它不能与“ update_idletasks”一起使用。 As per my knowledge it is also used to refresh the GUI events. 据我所知,它还用于刷新GUI事件。

There is no practical size limitation in the text widget. 文本小部件中没有实际的大小限制。

Without seeing how you're actually copying the data it's impossible to know for sure, but are you aware that Tkinter is single threaded? 没有看到您实际上是如何复制数据的,就不可能确定,但​​是您是否知道Tkinter是单线程的? If you have a command that takes a long time, the GUI will hang until that operation completes. 如果您的命令花费很长时间,则GUI将挂起,直到该操作完成。 This is because all GUI operations happen by responding to events, and while any individual command is running the event loop can't respond to events. 这是因为所有GUI操作都是通过响应事件发生的,并且在运行任何单独的命令时,事件循环都无法响应事件。

The workarounds are to have that long running operation run in a thread or a separate process. 解决方法是让长时间运行的操作在线程或单独的进程中运行。 Or, you can refactor that function so that small chunks of work can be done in each iteration of the event loop. 或者,您可以重构该功能,以便可以在事件循环的每次迭代中完成少量工作。 Be aware that if you use threads, you cannot directly write to the GUI widgets from this other thread. 请注意,如果使用线程,则无法从该其他线程直接写入GUI小部件。 You have to use a thread safe queue to send data between the threads. 您必须使用线程安全队列在线程之间发送数据。

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

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