Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Tkinter: How do I make my GUI responsive as long as a thread runs?

For example:

import threading
import time
import Tkinter


class MyThread(threading.Thread):

    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        print "Step Two"
        time.sleep(20)

class MyApp(Tkinter.Tk):

    def __init__(self):
        Tkinter.Tk.__init__(self)

        self.my_widgets()

    def my_widgets(self):
        self.grid()

        self.my_button = Tkinter.Button(self, text="Start my function",
                                          command=self.my_function)
        self.my_button.grid(row=0, column=0)

    def my_function(self):
        print "Step One" 

        mt = MyThread()
        mt.start()

        while mt.isAlive():
            self.update()

        print "Step Three"

        print "end"

def main():
    my_app = MyApp()
    my_app.mainloop()

if __name__ == "__main__":
    main()

Well, if I start my example it works as expected. I click on a button, my_function starts and the GUI is responsive. But I have read that I should avoid the use of update(). So, it would be nice if some one could explain why and how I have to wait for a thread correctly? Step Two is in a thread because it takes a much longer time than Step One and Step Three, otherwise it would block the GUI.

I'm new to Python and I trying to write my first "program". Maybe I'm thinking in a wrong way since I'm not very experienced...

Regards, David.

like image 304
davmue86 Avatar asked Jan 01 '26 05:01

davmue86


1 Answers

You need to remember that you have an event loop running, so all you need to do is check on the thread each time the event loop makes an iteration. Well, not every time, but periodically.

For example:

def check_thread(self):
    # Still alive? Check again in half a second
    if self.mt.isAlive():
        self.after(500, self.check_thread)
    else:
        print "Step Three"

def my_function(self):
    self.mt = MyThread()
    self.mt.start()
    self.check_thread()
like image 68
Bryan Oakley Avatar answered Jan 02 '26 18:01

Bryan Oakley



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!