tkinter - Python:如何重新启动被标志停止的线程
问题描述
我需要根据某些条件停止/启动线程。我可以使用标志来启动它然后停止它,但是当我尝试再次启动它时,我得到RuntimeError: threads can only be started once
例如,在以下代码中,用户按下退出键来启动或停止标签闪烁。第一次调用开始,第二次调用停止,但第三次调用我得到运行时错误。
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()
我将如何重新启动线程而不会出现此错误?谢谢你。
解决方案
您可以使用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()
推荐阅读
- django - Django 2/3 每次保存模型时只接收一个 post_save 生成的 celery 信号
- angular - Angular - 为什么我的弹珠测试不适用于包含用户权限的 BehaviorSubject?
- arrays - 如何对象数组不同的索引到索引只有一个?
- c - Visual Studio Code 中的 GDB 不显示 printf() 输出到标准输出
- android - Activity 在 onCreate 之后调用 onStop
- angular - 使用 Firebase 云消息传递 Angular 在 PWA 中处理来自推送通知的有效负载信息
- android - OKHttp 缓存响应的安全性
- google-cloud-firestore - Firestore 添加安全规则以仅允许从移动应用程序读取
- python - formset_factory 位于formsets.py 中,为什么要从django.forms 调用呢?
- html - 无法让图像具有正确的边界半径