我在写一个GUI,里面需要添加实时的时间,于是我开了个线程用来计时。代码如下:
import time
from threading import Thread
import tkinter as tk
import tkinter.ttk as ttk
from tkinter import StringVar
class TestUI(tk.Tk):
def __init__(self):
super().__init__()
self.w = 390
self.h = 200
self.x = (self.winfo_screenwidth() - self.w) / 2
self.y = (self.winfo_screenheight() - self.h) / 2
self.title("test")
self.geometry('%dx%d+%d+%d' % (self.w, self.h, self.x, self.y))
self.resizable(False, False)
self.str_time = StringVar() # for timing
self.build_ui()
def timing(self):
while True:
str_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
self.str_time.set(str_time)
time.sleep(1)
def build_ui(self):
frame_001 = ttk.Frame(self)
timing_thread = Thread(target=self.timing)
timing_thread.start()
ttk.Label(frame_001, width=40, textvariable=self.str_time).pack()
frame_001.pack()
if __name__ == '__main__':
root = TestUI()
root.mainloop()
运行后可以正常计时,但是每次关闭GUI,都会有下面的异常:
Exception in thread Thread-1 (timing):
Traceback (most recent call last):
File "C:\Users\*****\AppData\Local\conda\conda\envs\PyDataAnalysis\lib\threading.py", line 1016, in _bootstrap_inner
self.run()
File "C:\Users\*****\AppData\Local\conda\conda\envs\PyDataAnalysis\lib\threading.py", line 953, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\*****\PycharmProjects\tp_integrity\ui_test.py", line 26, in timing
self.str_time.set(str_time)
File "C:\Users\*****\AppData\Local\conda\conda\envs\PyDataAnalysis\lib\tkinter\__init__.py", line 402, in set
return self._tk.globalsetvar(self._name, value)
RuntimeError: main thread is not in main loop
请问这个是什么原因,应该怎么解决?
因为子线程没有在主线程退出时结束
可将子线程设置为守护线程,使其随主线程退出而结束,在timing_thread.start()前加上
timing_thread.setDaemon(True)
但这种在子线程中操作主线程ui组件的行为后续运行中可能会遇到意料之外的错误