存储Radiobuttons和Checkbuttons的值

时间:2015-04-20 02:18:07

标签: python python-2.7 tkinter

我正在尝试使用以下格式的用户界面

enter image description here

import pandas as pd
from Tkinter import *

features =  pd.read_csv("C:\\Users\\ggorantla\\Desktop\\Competition\\otto\\data\\train.csv",dtype=object)
features = features.columns
master = Tk()
row = 0
result = []
mappe = {}
def saver(each):
    print(each, v.get())
    result.append(v.get())
    mappe[each] = v.get()
MODES = [ ("String", "str"), ("Number","num")]
for each in features:
    if row >4 :
        continue
    Label(master, text=each).grid(row=row, column=0)
    v = StringVar()
    v.set("default")
    col = 1
    for text, mode in MODES:
        Radiobutton(master, text=text, variable=v,value = mode, command=saver(each)).grid(row=row,column=col)
        col+=1
    print(v.get())
    row += 1         
mainloop()

我的问题是当我运行此代码时,我按预期获得了UI,但我无法将所有变量存储在mappe字典或result列表中。

所有值默认为“默认”值。我坚持这个。

2 个答案:

答案 0 :(得分:1)

您为要素中的每个条目设置了新的StringVar v,但是您不保存之前的条目以便稍后引用它。您应该将v设为字典并将StringVar保存在其所属功能的键下。

此外,command参数需要对函数的引用,但是您给它一个函数调用,这意味着该函数的返回值将分配给command。因此,不应使用command=function(),而应使用command=function。因为要将变量传递给函数,所以需要command来调用一个调用实际函数的新函数。幸运的是,您可以使用像{/ p>这样的lambda函数轻松完成此操作

command = lambda: saver(each)

但是,因为lambda函数仅在调用它们时进行评估,所以您需要指定当时要使用each,而不是上次迭代时使用each 。你这样做是用

command = lambda each=each: saver(each)

然后,为了保存输入,我建议使用字典而不是列表,因为你使用他们的名字引用features中的项目,而不是他们的索引。

结合所有这些,您的计划将成为:

from Tkinter import *

features = ['a', 'b', 'c', 'd']
master = Tk()
row = 0
mappe = {}
v = {}

def saver(each):
    print(each, v[each].get())
    mappe[each] = v[each].get()
    print mappe

MODES = [ ("String", "str"), ("Number","num")]

for each in features:

    if row >4 :
        continue

    Label(master, text=each).grid(row=row, column=0)
    v[each] = StringVar()
    v[each].set("default")
    col = 1

    for text, mode in MODES:
        Radiobutton(master, text=text, variable=v[each],value = mode, command=lambda feature=each: saver(feature)).grid(row=row,column=col)
        col+=1

    row += 1   

master.mainloop()

答案 1 :(得分:0)

这也把我绊倒了。接口对我来说是不一致的,因为父框架仍然存在,但是传递给工厂的其他变量却没有。另一个解决方法是用其猴子修补父级。感觉就像是黑客,我无法说出它是Pythonish的样子,但是从某种意义上说,它看起来非常优雅。

label = Label(master, text=each).grid(row=row, column=0)
label.v = StringVar() 
label.v.set("Default")
for text, mode in MODES:
    Radiobutton(master, text=text, variable=label.v, value = mode, 
                command=saver(each)).grid(row=row,column=col)      
    col+=1
    print(label.v.get())
    row += 1 

这将导致变量在没有其他情况的情况下得以保留。可以理解,冒着覆盖Label类中现有变量的风险。但是,它确实消除了在变量分配给标签的范围之外跟踪变量的需求。