我刚遇到一些令我难过的奇怪行为。我正在为一些内部数据处理编写一个简单的小GUI。我想允许用户在几种不同的数据处理模式之间切换,并输入一些参数,这些参数定义了如何为每种模式处理数据。问题是当用户输入新参数时,应用程序会忽略切换模式的请求。
以下代码会复制此问题。我为大小道歉,这是复制问题的最短代码。
import Tkinter as Tk
class foo(Tk.Frame):
def __init__(self):
self.master = master =Tk.Tk()
Tk.Frame.__init__(self,self.master) #Bootstrap
#Here mode and parameters as key, value pairs
self.data = {'a':'Yay',
'b':'Boo'
}
self.tex = Tk.Text(master=master)
self.tex.grid(row=0,column=0,rowspan=3,columnspan=4)
self.e = Tk.Entry(master=master)
self.e.grid(row=3,column=0,columnspan=4)
self.sv =Tk.StringVar()
self.sv.set('a')
self.b1 = Tk.Radiobutton(master=master,
text = 'a',
indicatoron = 0,
variable = self.sv,
value = 'a')
self.b2 = Tk.Radiobutton(master=master,
text = 'b',
indicatoron = 0,
variable = self.sv,
value = 'b')
self.b3 = Tk.Button(master = master,
text='Apply',command=self.Apply_Func)
self.b4 = Tk.Button(master = master,
text='Print',command=self.Print_Func)
self.b1.grid(row=4,column=0)
self.b2.grid(row=4,column=1)
self.b3.grid(row=4,column=2)
self.b4.grid(row=4,column=3)
def Apply_Func(self):
self.innerdata = self.e.get()
def Print_Func(self):
self.tex.insert(Tk.END,str(self.innerdata)+'\n')
#This is how I'm retrieving the user selected parameters
@property
def innerdata(self):
return self.data[self.sv.get()]
#And how I'm setting the user defined parameters
@innerdata.setter
def innerdata(self,value):
self.data[self.sv.get()] = value
if __name__ == "__main__":
app = foo()
app.mainloop()
预期行为:
1)按“a”按钮,然后“打印”打印:
Yay
2)按“b”按钮,然后“打印”打印:
啵
3)在输入字段中输入“Zep Rocks”,然后按“应用”
4)现在按“打印”会产生
Zep Rocks
5)按'a'然后'print'应该产生
耶
而是收益
Zep Rocks
这可能是真的,但现在并不需要。这是怎么回事?
编辑:我有一些新信息。 python 2.7中的Tk.Frame不是一个新式的类。它与描述符不友好,因此它不是将'='解释为使用foo.innerdata的__set__
方法的请求,而只是将self.e.get()的结果赋给innerdata。
ARGLEBARGLE !!!
仍然是一个悬而未决的问题:我怎样才能以干净的方式做到我想做的事情?
答案 0 :(得分:0)
所以核心问题是Tk.Frame不是从对象的子类,所以它不是一个新式的python类。这意味着它不会像我试图使用的那样描述。我找到的一个解决方案是从对象中继承我的应用程序。
解决我的问题的代码如下:
import Tkinter as Tk
class foo(object):
def __init__(self,master):
self.master = master #Bootstrap
self.mainloop = master.mainloop
self.data = {'a':{'value':7,'metavalue':False},
'b':{'value':'Beeswax','metavalue':True}
}
self.tex = Tk.Text(master=master)
self.tex.grid(row=0,column=0,rowspan=3,columnspan=4)
self.e = Tk.Entry(master=master)
self.e.grid(row=3,column=0,columnspan=4)
self.sv =Tk.StringVar()
self.sv.set('a')
self.b1 = Tk.Radiobutton(master=master,
text = 'a',
indicatoron = 0,
variable = self.sv,
value = 'a')
self.b2 = Tk.Radiobutton(master=master,
text = 'b',
indicatoron = 0,
variable = self.sv,
value = 'b')
self.b3 = Tk.Button(master = master,text='Apply',command=self.Apply_Func)
self.b4 = Tk.Button(master = master,text='Print',command=self.Print_Func)
self.b1.grid(row=4,column=0)
self.b2.grid(row=4,column=1)
self.b3.grid(row=4,column=2)
self.b4.grid(row=4,column=3)
def Apply_Func(self):
self.innerdata = self.e.get()
def Print_Func(self):
self.tex.insert(Tk.END,str(self.innerdata)+'\n')
@property
def innerdata(self):
return self.data[self.sv.get()]
@innerdata.setter
def innerdata(self,value):
self.data[self.sv.get()] = value
if __name__ == "__main__":
master = Tk.Tk()
app = foo(master)
app.mainloop()