Tkinter and lengthy computations

Olaf Delgado delgado at eva17.Mathematik.Uni-Bielefeld.DE
Tue Mar 19 02:25:53 EST 2002


Hi all!

What is good way to prevent a GUI from blocking during lengthy
computations? Actually, the only thing I need is to have the
application's main window be redrawn each time it becomes visible, so
the user can do something else and come back from time to time to
check the progress.

After studying the documentation and the cookbook for inspiration, the
solution I came up with is to initiate a daemonic "worker" thread on
startup which receives tasks from and returns results to the GUI via
two Queues (see example code at the bottom). It seems to work fine, so
far, but looks somewhat complicated to me. Maybe I am missing
something obvious. I am actually more an algorithms man than an
application programmer and have never touched threads before.

Cheers,
Olaf


# ============================================================
import Tkinter
import threading
import Queue
import time


class GUI:
    def __init__(self, master, tasks, results):
        self.tasks = tasks
        self.results = results
        self.counter = 0

        self.master = master
        Tkinter.Button(master, text = "Work!", command =
        self.work).pack()
        self.output = Tkinter.Label(master, text = "")
        self.output.pack()
        self.poll()

    def work(self):
        self.counter = self.counter + 1
        self.tasks.put(self.counter)

    def poll(self):
        try:
            item = self.results.get_nowait()
        except Queue.Empty:
            pass
        else:
            self.output.configure(text = str(item))
        self.master.after(100, self.poll)


def work(tasks, results):
    while 1:
        try:
            task = tasks.get_nowait()
        except Queue.Empty:
            time.sleep(0.1)
        else:
            results.put("Task %s started." % task)

            # Pretend to do a lengthy computation:
            time.sleep(20)

            results.put("Task %s completed." % task)


tasks = Queue.Queue(1)
results = Queue.Queue(1)

worker = threading.Thread(target = work, args = (tasks, results))
worker.setDaemon(1)
worker.start()

root = Tkinter.Tk()
root.title("Threading test")
GUI(root, tasks, results)
root.mainloop()
# ============================================================

-- 
   ////         Olaf Delgado Friedrichs, Dept. of Chemistry,
   Olaf         Arizona State University, Tempe AZ 85287, USA
   `='            phone +1-480-965-6570  fax +1-480-965-2747
                  http://www.mathematik.uni-bielefeld.de/~delgado



More information about the Python-list mailing list