【问题标题】:Python Tkinter Threading - How to end / kill / stop thread when user closes GUIPython Tkinter 线程 - 当用户关闭 GUI 时如何结束/杀死/停止线程
【发布时间】:2018-02-04 18:01:54
【问题描述】:

如果我有一个非 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()。但我也不知道该怎么做

【问题讨论】:

    标签: python multithreading tkinter


    【解决方案1】:

    当您使用要中断的线程时,您应该使用Event 对象并使用wait() 方法而不是time.sleep

    这可能对你有帮助:

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

    【讨论】:

      猜你喜欢
      • 2014-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多