Tkinter Python:如何重新启动由标志停止的线程

Tkinter Python:如何重新启动由标志停止的线程,tkinter,python-3.6,python-multithreading,Tkinter,Python 3.6,Python Multithreading,我需要根据特定条件停止/启动线程。我可以使用一个标志启动它,然后停止它,但是当我再次尝试启动它时,我会得到RuntimeError:线程只能启动一次 例如,在以下代码中,用户按escape键启动或停止标签闪烁。第一次调用开始,第二次调用停止,但第三次调用我得到运行时错误 from tkinter import * import threading import time class App: def __init__(self, master): self.label

我需要根据特定条件停止/启动线程。我可以使用一个标志启动它,然后停止它,但是当我再次尝试启动它时,我会得到
RuntimeError:线程只能启动一次

例如,在以下代码中,用户按escape键启动或停止标签闪烁。第一次调用开始,第二次调用停止,但第三次调用我得到运行时错误

from tkinter import *
import threading
import time

class App:
    def __init__(self, master):
        self.label = Label(text="TEXT?", font=('Helvetica', 30))
        self.label.pack()
        self.labelFlash = False
        self.t = threading.Thread(target=self.flash)
        root.bind("<Escape>", self.flashEvent)
    def flashEvent(self, event):
        if self.labelFlash == False:
            self.labelFlash = True
            self.t.start()
        elif self.labelFlash == True:
            self.labelFlash = False
            print(self.labelFlash)
    def flash(self):
        while self.labelFlash == True:
            self.label.config(bg='red')
            root.update()
            time.sleep(.5)
            self.label.config(bg='green')
            root.update()
            time.sleep(.5)
root = Tk()
app = App(root)
root.mainloop()
从tkinter导入*
导入线程
导入时间
类应用程序:
定义初始(自我,主):
self.label=label(text=“text?”,font=('Helvetica',30))
self.label.pack()
self.labelFlash=False
self.t=threading.Thread(target=self.flash)
root.bind(“,self.flashvent)
def闪蒸通风(自身、事件):
如果self.labelFlash==False:
self.labelFlash=True
self.t.start()
elif self.labelFlash==真:
self.labelFlash=False
打印(self.labelFlash)
def闪存(自):
当self.labelFlash==True时:
self.label.config(bg='red')
root.update()
时间。睡眠(.5)
self.label.config(bg='green')
root.update()
时间。睡眠(.5)
root=Tk()
app=app(根目录)
root.mainloop()

如何重新启动线程而不出现此错误?谢谢。

您可以使用
threading.Event
对象来控制线程何时回调到gui中。但是在事件循环线程之外调用gui是非法的,最终会导致崩溃。相反,请使用
after()
方法在循环中计划定时事件。此事件可以安全地更改背景颜色,并可以取消以暂停操作

from tkinter import *
import threading
import time

class App:
    def __init__(self, master):
        self.master = master
        self.flash_colors = ['red', 'green']
        self.cur_color = 0
        self.flash_timer_id = None
        self.label = Label(text="TEXT?", font=('Helvetica', 30))
        self.label.pack()
        root.bind("<Escape>", self.flashEvent)

    def flashEvent(self, event):
        if self.flash_timer_id is None:
            # start flashing
            self.flash()
        else:
            # stop flashing
            self.master.after_cancel(self.flash_timer_id)
            self.flash_timer_id = None

    def flash(self):
        self.label.config(bg=self.flash_colors[
            self.cur_color%len(self.flash_colors)])
        self.cur_color += 1
        root.update()
        # (delay in mS)
        self.flash_timer_id = self.master.after(500, self.flash)

root = Tk()
app = App(root)
root.mainloop()
从tkinter导入*
导入线程
导入时间
类应用程序:
定义初始(自我,主):
self.master=master
self.flash_colors=[“红色”、“绿色”]
self.cur\u color=0
self.flash\u timer\u id=None
self.label=label(text=“text?”,font=('Helvetica',30))
self.label.pack()
root.bind(“,self.flashvent)
def闪蒸通风(自身、事件):
如果self.flash\u timer\u id为无:
#开始闪烁
self.flash()
其他:
#停止闪烁
self.master.after\u cancel(self.flash\u timer\u id)
self.flash\u timer\u id=None
def闪存(自):
self.label.config(bg=self.flash\u颜色[
自发光颜色%len(自发光颜色)])
self.cur_color+=1
root.update()
#(延迟毫秒)
self.flash\u timer\u id=self.master.after(500,self.flash)
root=Tk()
app=app(根目录)
root.mainloop()