【问题标题】:Setting and Retrieving Data with TkInter使用 TkInter 设置和检索数据
【发布时间】:2016-06-15 20:21:44
【问题描述】:

我刚刚遇到了一些让我难过的奇怪行为。我正在为一些内部数据处理编写一个简单的小 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”然后“打印”打印:

2) 按下按钮“b”然后打印“打印”:

3) 在输入字段中输入“Zep Rocks”并按应用

4) 现在按下“打印”会产生

Zep 岩石

5) 按 'a' 然后按 'print' 应该会产生

是的

而是产生了

Zep 岩石

这可能是真的,但现在并不理想。这是怎么回事?

编辑:我有一些新信息。 python 2.7 中的 Tk.Frame 不是新式类。它对描述符不友好,因此它不会将 '=' 解释为使用 foo.innerdata 的 __set__ 方法的请求,而是将 self.e.get() 的结果分配给 innerdata。

阿格巴格!!!

仍然是一个悬而未决的问题:我如何让它以干净的方式做我想做的事?

【问题讨论】:

    标签: python-2.7 tkinter python-decorators


    【解决方案1】:

    所以核心问题是 Tk.Frame 不是对象的子类,所以它不是一个新式的 python 类。这意味着它不会像我试图使用的那样使用描述符。我发现的一种解决方案是从 object 子类化我的应用程序。

    解决我的问题的代码如下:

    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()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-16
      • 2014-10-20
      • 1970-01-01
      • 2012-01-09
      • 2016-09-14
      相关资源
      最近更新 更多