我创建了一个简单的tkinter应用程序,其中使用了两个线程。他们的任务是将数字写入小部件,如标签和文本。一个线程由按钮(单击事件)触发,第二个线程作为后台线程执行。
import Tkinter as tk
from ttk import *
from Tkconstants import *
import threading, thread, time
def tl1(text,counter):
while True:
text.insert(END,counter)
counter += 1
time.sleep(2)
def tl2(label,counter):
while True:
label['text'] = counter
counter += 1
time.sleep(1)
class mainWindow():
def __init__(self, master):
self.master = master
self._initLayout()
def _initLayout(self):
#button
self.button = tk.Button(self.master, text="thread1_start", command = self._task1)
self.button.pack()
#label
self.label = tk.Label(self.master)
self.label.pack()
#text
self.text = tk.Text(self.master, width=30)
self.text.pack()
def _task1(self):
t1 = thread.start_new_thread(tl1,(self.text,1))
def _task2(self):
t2 = thread.start_new_thread(tl2,(self.label,1000))
class App(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.mainWindow = mainWindow(self)
self.mainWindow._task2() #background_thread
app = App()
app.mainloop()
通过这种方式,一切正常,但如果我们更改背景线程以在文本小部件上显示结果,则整个应用程序会冻结。
为什么后台线程可以很好地与标签通信,但会导致文本小部件出现问题有没有办法正确运行它?
答案 0 :(得分:1)
Tkinter不是线程安全的。您只能从创建它们的线程访问小部件。您的线程需要将数据放在线程安全的队列中,并且您的GUI线程需要轮询队列。
在您的特定情况下,您根本不需要线程。您可以使用tkinter after
方法定期运行代码。