1

In my application, I have a process which runs on another thread, takes a few seconds to complete and only needs to be done once. I also have a loading window which would let users know that the application is still running and let them cancel the process. This loading window calls a function every 0.5s to update the message : Processing., Processing.. or Processing... in a cycle.

The problem I have is that the computing time increases significantly with the loading window. Here are the 2 different implementation :

Without loading window :

processing_thread.start()
processing_thread.join()

With loading window :

processing_thread.start()

loading_window = LoadingWindow()

while processing_thread.is_alive():
    try:
        loading_window.window.update_idletasks()
        loading_window.window.update()
    except TclError:
        return

Note that I don't use mainloop but an equivalent implementation which enables me the check if my process is still running - a bit like join and mainloop merged together (Tkinter understanding mainloop). I also tested it with mainloop() and it still didn't reduce the processing time in a significant way.

For now, the quick fix was to slow down the loop and add more idle time in the main thread :

processing_thread.start()

loading_window = LoadingWindow()

while processing_thread.is_alive():
    try:
        loading_window.window.update_idletasks()
        loading_window.window.update()
        time.sleep(0.5)
    except TclError:
        return

This reduced the time to something similar to what I have without the loading window but it brings me 2 problems (as far as I could see) :

  • Response time is slower (0.5s at worst)
  • The application will end some time after the process ended (0.5s at worst)

Is there a way to implement this without these drawbacks? Would multiprocessing (https://docs.python.org/3/library/multiprocessing.html#module-multiprocessing) solve this?

Thank you

Olivier Samson
  • 609
  • 4
  • 13
  • FWIW, you don't need to call `update_idletasks` if you call `update` immediately after. `update` does everything `update_idletasks` does and more. – Bryan Oakley May 31 '18 at 12:10
  • Please show the solution you had which used `mainloop`. Using `mainloop` is almost certainly the most efficient way, assuming you're using it properly. – Bryan Oakley May 31 '18 at 12:11
  • @BryanOakley the implementation using `mainloop` is something I did only to test. Instead of looping over `update_idletasks` and `update` I called `mainloop`. The problem was that I didn't find a viable way to end the loop when the process ends (I had to do it manually) and only did it to see if it made a difference. As for calling `update_idletasks`, I don't see any significant difference whether I remove it or not. Thanks. – Olivier Samson May 31 '18 at 14:22

0 Answers0