2

I have a Python GUI tkinter application.

When I press a button in my GUI, I have a long-running task to perform.
So I want to run this task in another thread and only when it's done, update some GUI elements e.g. add text to some Text widget. And while it's running I want to e.g. update some status bar so that process is nicely visible to the user.

I had done this in Java long ago using SwingUtilities.invokeLater

https://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html

  1. What is the Python analogue or say best practice for this kind of thing?

  2. Could you point me to some references or provide me with a simple example?

  3. Also... in Python... does it matter if I handle the long running task in a thread or in a process? Will the UI updating code/technique be different?

peter.petrov
  • 38,363
  • 16
  • 94
  • 159
  • I would suggest to `thread` the task and add the results to a `queue`. The main GUI will then process the `queue` at regular intervals. There is a good sample [here](https://stackoverflow.com/questions/16745507/tkinter-how-to-use-threads-to-preventing-main-event-loop-from-freezing/16747734#16747734). – Henry Yik Oct 13 '20 at 15:57
  • In this Question we had discuss with some references, it may help you out. https://stackoverflow.com/questions/63414254/tkinter-gui-i-o-threading-when-to-use-queues-when-events/63416839#63416839 – Thingamabobs Oct 13 '20 at 16:02
  • @HenryYik So there is no way to post directly some work to the GUI thread as in Java with `SwingUtilities.invokeLater`? Instead in the worker, we post to some queue, and the GUI thread checks that queue at regular intervals and acts accordingly? This is the best we can do in Python? I mean `SwingUtilities.invokeLater` has no analogue in Python you're saying... correct? – peter.petrov Oct 13 '20 at 16:06
  • This is a common way to do so, yes. Another way is to use a variable as a flag like I did. – Thingamabobs Oct 13 '20 at 16:09
  • Since `tkinter` is single-threaded, directly working with the GUI thread is not thread-safe which might result in undesired behaviour. You can read more on Bryan's answer [here](https://stackoverflow.com/a/10848959/9284423). `tkinter` does have an [`after`](http://effbot.org/tkinterbook/widget.htm#Tkinter.Widget.after-method) method but it still runs within the main thread. – Henry Yik Oct 13 '20 at 16:39
  • @HenryYik I didn't mean directly working with the GUI/main thread. This is not what `SwingUtilities.invokeLater` does. It's basically saying: "here is a task (small one e.g. setting a label, or adding text in some box), go ahead and run it in the GUI thread when you have time for that". It's a pretty smart thing which obviously Python does not have. In Python the developer needs to simulate this himself. Thanks anyway. – peter.petrov Oct 13 '20 at 20:00

0 Answers0