简体   繁体   中英

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. It uses customized shutil module for copying files. 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). Now the problem is when I use the GUI for performing same operation, it hung after some time.

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.

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? 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. 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". Now my question why it didn't worked with "update_idletasks". As per my knowledge it is also used to refresh the GUI events.

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? If you have a command that takes a long time, the GUI will hang until that operation completes. 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.

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. You have to use a thread safe queue to send data between the threads.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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