Why use a thread with a GUI application?

Graphical applications tend to execute everything in the main thread. This means that updates to its widgets happen in line with all other code that is currently executing.

As a result of this, any slow processing will often block the updating of the GUI. We can demonstrate this with a small example:

import tkinter as tk
import time

win = tk.Tk()
win.geometry("200x150")

counter = tk.IntVar()
label = tk.Label(win, text="Ready to Work")
counter_label = tk.Label(win, textvar=counter)

The example starts with a window which will contain a Label displaying the value of an IntVar.

We will be creating a button that increases the value stored in the IntVar, as well as another button which will simulate a very heavy processing task (using time.sleep).

Before we can create the buttons, we will need the functions they will call:

def increase_counter():
counter.set(counter.get() + 1)

def work():
label.configure(text="Doing work")
time.sleep(5)
label.configure(text="Finished")

With these functions defined, we can finish the example off by creating the buttons and then packing all of our widgets:

counter_button = tk.Button(win, text="Increase Counter", command=increase_counter)
work_button = tk.Button(win, text="Work", command=work)

label.pack()
counter_label.pack()

counter_button.pack()
work_button.pack()

win.mainloop()

Save and run this file and you should see a small window appear:

Click the Increase Counter button a few times and notice how it will add one to the number above it.

Now, click the Work button and observe how it appears to get stuck in the pressed state. While it is like this, the rest of the program doesn't appear to respond.

Once it has finished and the label shows Finished, try pressing it once more. While it is stuck down, click the Increase Counter button a few times, then wait for it to finish once again.

You should then notice that even though the Increase Counter button did not appear to respond to your clicks, the number above it will increase as the other task completes.

Finally, press the Work button one more time, then close the window. You should see that the window will not close until the five second sleep has finished.

This behavior is very undesirable. When a large task needs to execute, if the GUI elements stop responding, a user may click something multiple times thinking it is not working, only to realize that it was indeed functioning and they have now performed an action more times than they intended.

We also do not want to prevent the user from closing an application for a long period of time, since they may end up force-closing it, which can lead to problems such as loss of data.

So, how do we perform a large task without locking up the GUI? One possible solution is to use a separate thread.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset