存储单选按钮和复选按钮的值
Store the values of Radiobuttons and Checkbuttons
我正在尝试获取以下格式的 UI
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
列表。
所有值默认为"default"值。我坚持这个。
您为功能中的每个条目都创建了一个新的 StringVar
v
,但您没有保存前一个以供以后参考。您应该将 v
设为字典,并将 StringVar
保存在它们所属的特征的键下。
此外,command
参数需要一个函数引用,但你给它一个函数调用,这意味着该函数的 return 值将被分配给 command
.因此,不应使用 command=function()
,而应使用 command=function
。因为要将变量传递给函数,所以需要 command
来调用调用实际函数的新函数。幸运的是,您可以使用像
这样的 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()
这也把我绊倒了。接口对我来说感觉不一致,因为父框架仍然存在,但传递到工厂的其他变量却没有。另一种解决方法是用它来猴子修补父级。感觉像是 hack,我不能说它有多 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
这将导致变量在没有其他情况时持续存在。可以理解,您 运行 有覆盖标签 class 中现有变量的风险。但是,它确实消除了跟踪分配给标签的范围之外的变量的需要。
我正在尝试获取以下格式的 UI
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
列表。
所有值默认为"default"值。我坚持这个。
您为功能中的每个条目都创建了一个新的 StringVar
v
,但您没有保存前一个以供以后参考。您应该将 v
设为字典,并将 StringVar
保存在它们所属的特征的键下。
此外,command
参数需要一个函数引用,但你给它一个函数调用,这意味着该函数的 return 值将被分配给 command
.因此,不应使用 command=function()
,而应使用 command=function
。因为要将变量传递给函数,所以需要 command
来调用调用实际函数的新函数。幸运的是,您可以使用像
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()
这也把我绊倒了。接口对我来说感觉不一致,因为父框架仍然存在,但传递到工厂的其他变量却没有。另一种解决方法是用它来猴子修补父级。感觉像是 hack,我不能说它有多 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
这将导致变量在没有其他情况时持续存在。可以理解,您 运行 有覆盖标签 class 中现有变量的风险。但是,它确实消除了跟踪分配给标签的范围之外的变量的需要。