我正在使用一个名为pyepics的软件包来读取某些硬件的通道(在这种情况下说是湿度)。这具有在值更改时运行回调的功能。我想在gui中显示新值。
import Tkinter
import epics
global root
class AlarmGUI:
def __init__(self,parent):
self.ending = False
Tkinter.Label(text="Weather Alarm",bg="AntiqueWhite2",font=("Helvetica", 10,"bold")).grid(row=0,columnspan=2)
self.grh2l = Tkinter.Label(text='CFHT RH')
self.grh2l.grid(row=1,column=2,padx=10,pady=10,sticky=Tkinter.E)
def cfh(self,value=None,**kw):
print 'value is',value
if (value < 80):
self.grh1 =Tkinter.Label(text=value,bg='Green')
self.grh1.grid(row=2,column=2, padx=10, pady=10)
elif (value > 80 and value < 85):
self.grh1 =Tkinter.Label(text=value,bg='Yellow')
self.grh1.grid(row=2,column=2, padx=10, pady=10)
else:
self.grh1 =Tkinter.Label(text=value,bg='Red')
self.grh1.grid(row=2,column=2, padx=10, pady=10)
return gw
def CFHTWeather():
ag = AlarmGUI(root)
crh = epics.PV('ws:wsHumid',callback=ag.cfh,auto_monitor=True).get()
return cw
def main():
global root
root = Tkinter.Tk()
root.wm_title('Weather Alarms')
gui = AlarmGUI(root)
cw = CFHTWeather()
root.mainloop()
if __name__ == '__main__':
main()
但是我得到了Tkinter.Label一行应该显示新值的投诉。
File "./weatherAlarm.py", line 73, in cfh
self.grh1 =Tkinter.Label(text=value,bg='Red')
File "/usr/lib64/python2.6/lib-tk/Tkinter.py", line 2466, in __init__
Widget.__init__(self, master, 'label', cnf, kw)
File "/usr/lib64/python2.6/lib-tk/Tkinter.py", line 1932, in __init__
(widgetName, self._w) + extra + self._options(cnf))
_tkinter.TclError: out of stack space (infinite loop?)
如果您对PyEpics信息以及我正在使用的PV类感兴趣,请访问:http://cars9.uchicago.edu/software/python/pyepics3/
我从其他关于这个“堆栈空间”的问题中看到它可能是因为我正在运行另一个无限循环。但我不明白我的代码是如何做到的 - 我想要的只是在频道改变时改变的gui。 PV类中的回调功能本身是无限循环吗?
答案 0 :(得分:1)
没有看到PV类无法肯定地说,但看起来你每次调用回调ag.cfh
时都会重新创建所有小部件,而且你看看这会导致out of stack space
错误。
而不是像你正在做的那样重新创建小部件来更新它们的值。您应该使用其他小部件将标签的创建移至__init__
方法,然后使用self.grh1['text'] = value
和self.grh1['background'] = some_color
更新小部件。
注意,背景不会自动更改。由于每次都创建了一个新的小部件,我假设它在你的情况下。
或者,您可以创建一个类属性来检查窗口小部件是否已经创建(即 - 计数器或布尔值),并且仅当此计数器小于指定值或某些值时才使用if语句创建窗口小部件如果您不希望在__init__
开始时自动创建窗口小部件,请进行其他适当的检查。
另外,我应该注意,从您发布的代码块看来global root
似乎是多余的,不需要这个。另外,并非真正的错误,但我发现的一个奇怪之处在于您将root作为父级传递,并且未在创建小部件时指定父级。如果您将tkinter帧作为父级传递,该怎么办?小部件被隐式创建到根窗口。