簡體   English   中英

Python Tkinter Threading-如何在用戶關閉GUI時結束/殺死/停止線程

[英]Python Tkinter Threading - How to end / kill / stop thread when user closes GUI

如果我有一個非for循環線程任務與tkinter一起運行,例如time.sleep(seconds)如何在任務結束之前或time.sleep()結束之前安全地結束該任務。

如果運行該程序並單擊按鈕,然后關閉GUI窗口,則幾秒鍾后仍將在解釋器窗口中打印finished

請注意,在這種情況下, time.sleep()只是長時間運行的非for循環函數的占位符。

# python 3 imports
import tkinter as tk
import threading
import queue
import time

def center_app(toplevel):
    toplevel.update_idletasks()
    w = toplevel.winfo_screenwidth() - 20
    h = toplevel.winfo_screenheight() - 100
    size = tuple(int(Q) for Q in toplevel.geometry().split("+")[0].split("x"))
    toplevel.geometry("%dx%d+%d+%d" % (size + (w / 2 - size[0] / 2, h / 2 - size[1] / 2)))

class app(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.protocol("WM_DELETE_WINDOW", self.USER_HAS_CLOSED_WINDOW)
        self.b1 = tk.Button(self, text = "*** Start Thread ***", font = ("Arial",25,"bold"), command = self.func_1)
        self.b1.pack(side = "top", fill = "both", expand = True)
        center_app(self)
        self.queue = queue.Queue()

    def USER_HAS_CLOSED_WINDOW(self, callback = None):
        print ("attempting to end thread")
        # end the running thread
        self.destroy()

    def func_1(self):
        self.b1.config(text = " Thread Running ")
        self.b1.update_idletasks()
        t = ThreadedFunction(self.queue).start()
        self.after(50, self.check_queue)

    def check_queue(self):
        try:
            x = self.queue.get(0) # check if threaded function is done
            self.b1.config(text = "*** Start Thread ***")
            self.b1.update_idletasks()
        except:
            self.after(50, self.check_queue)

class ThreadedFunction(threading.Thread):
    def __init__(self, queue):
        threading.Thread.__init__(self, daemon = True)
        self.queue = queue
    def run(self):
        time.sleep(10) # how to end this if user closes GUI
        print ("finished")
        self.queue.put("result")

a = app()
a.mainloop()

我已經創建了一個函數USER_HAS_CLOSED_WINDOW來捕獲關閉窗口的用戶,我當時以為我可以放一些東西來結束正在運行的線程,但是我不確定如何做。

我猜另一個選擇是在線程上放置適當的timeout並以某種方式使用.join() 但是我也不知道該怎么做

似乎在使用要中斷的time.sleep時,應該使用Event對象並使用wait()方法,而不是time.sleep

可能可以幫助您:

  1. https://stackoverflow.com/a/5205180
  2. https://stackoverflow.com/a/38828735

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM