您需要在主线程中运行GUI代码,而温度读取代码需要在后台线程中。仅在主线程中更新GUI是安全的,因此您可以通过将从后台线程读取的温度数据通过传递回主线程
Queue,并使主线程使用以下命令定期检查队列中的数据
self.root.after():
from Tkinter import *import tkFontimport osimport globimport timeimport threadingimport Image import Queuedef update_temp(queue): """ Read the temp data. This runs in a background thread. """ while True: # 28-000005c6ba08 i = "28-000005c6ba08" base_dir = '/sys/bus/w1/devices/' device_folder = glob.glob(base_dir + i)[0] device_file = device_folder + '/w1_slave' tempread=round(read_temp(),1) # Pass the temp back to the main thread. queue.put(tempread) time.sleep(5)class Gui(object): def __init__(self, queue): self.queue = queue #Make the window self.root = Tk() self.root.wm_title("Home Management System") self.root.minsize(1440,1000) self.equipTemp = StringVar()self.equipTemp1 = StringVar() self.equipTemp2 = StringVar() self.customFont = tkFont.Font(family="Helvetica", size=16) # 1st floor Image img = Image.open("HOUSE-PLANS-01.png") photo = ImageTk.PhotoImage(img) Label1=Label(self.root, image=photo) Label1.place(x=100, y=100) # 2nd floor img2 = Image.open("HOUSE-PLANS-02.png") photo2 = ImageTk.PhotoImage(img2) Label1=Label(self.root, image=photo2) Label1.place(x=600, y=100) # basement image img3 = Image.open("HOUSE-PLANS-03.png") photo3 = ImageTk.PhotoImage(img3) Label1=Label(self.root, image=photo3) Label1.place(x=100, y=500) # Attic Image img4 = Image.open("HOUSE-PLANS-04.png") photo4 = ImageTk.PhotoImage(img4) Label1=Label(self.root, image=photo4) Label1.place(x=600, y=500) # House Isometric Image img5 = Image.open("house-iso.png") photo5 = ImageTk.PhotoImage(img5) Label1=Label(self.root, image=photo5) Label1.place(x=1080, y=130) #Garage Temp Label Label2=Label(self.root, textvariable=self.equipTemp, width=6, justify=RIGHT, font=self.customFont) Label2.place(x=315, y=265) print "start monitoring and updating the GUI" # Schedule read_queue to run in the main thread in one second. self.root.after(1000, self.read_queue) def read_queue(self): """ Check for updated temp data""" try: temp = self.queue.get_nowait() self.equipTemp.set(temp) except Queue.Empty: # It's ok if there's no data to read. # We'll just check again later. pass # Schedule read_queue again in one second. self.root.after(1000, self.read_queue)if __name__ == "__main__": queue = Queue.Queue() # Start background thread to get temp data t = threading.Thread(target=update_temp, args=(queue,)) t.start() print "starting app" # Build GUI object gui = Gui(queue) # Start mainloop gui.root.mainloop()编辑:
之后实际上正在看看Tkinter的源代码,以及Python的bug跟踪系统,似乎与几乎所有其它的GUI库那里,Tkinter的 是
意是线程安全的,只要你在主线程中运行的主循环的应用程序。见我添加的答案在这里获得更多信息,或者直接去解决问题,关于Python的bug跟踪系统的Tkinter的线程安全性在这里。如果tkinter源代码和Python的错误跟踪器是正确的,那意味着只要您在主线程中运行mainloop,就可以
gui.equipTemp.set()直接从温度读取线程中愉快地调用-
Queue不需要。在我的测试中,确实确实很好。



