Tkinter: How to use threads to preventing main event loop from “freezing”

后端 未结 4 943
囚心锁ツ
囚心锁ツ 2020-11-21 23:25

I have a small GUI test with a \"Start\" button and a Progress bar. The desired behavior is:

  • Click Start
  • Progressbar oscillates for 5 seconds
4条回答
  •  半阙折子戏
    2020-11-22 00:09

    When you join the new thread in the main thread, it will wait until the thread finishes, so the GUI will block even though you are using multithreading.

    If you want to place the logic portion in a different class, you can subclass Thread directly, and then start a new object of this class when you press the button. The constructor of this subclass of Thread can receive a Queue object and then you will be able to communicate it with the GUI part. So my suggestion is:

    1. Create a Queue object in the main thread
    2. Create a new thread with access to that queue
    3. Check periodically the queue in the main thread

    Then you have to solve the problem of what happens if the user clicks two times the same button (it will spawn a new thread with each click), but you can fix it by disabling the start button and enabling it again after you call self.prog_bar.stop().

    import Queue
    
    class GUI:
        # ...
    
        def tb_click(self):
            self.progress()
            self.prog_bar.start()
            self.queue = Queue.Queue()
            ThreadedTask(self.queue).start()
            self.master.after(100, self.process_queue)
    
        def process_queue(self):
            try:
                msg = self.queue.get(0)
                # Show result of the task if needed
                self.prog_bar.stop()
            except Queue.Empty:
                self.master.after(100, self.process_queue)
    
    class ThreadedTask(threading.Thread):
        def __init__(self, queue):
            threading.Thread.__init__(self)
            self.queue = queue
        def run(self):
            time.sleep(5)  # Simulate long running process
            self.queue.put("Task finished")
    

提交回复
热议问题