简体   繁体   English

存储 Radiobuttons 和 Checkbuttons 的值

[英]Store the values of Radiobuttons and Checkbuttons

I am trying to get a UI in the below format我正在尝试获取以下格式的 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()

My problem is when i run this code, I get the UI as expected, but I am not able to store all the variables in the mappe dictionary or the result list.我的问题是当我运行此代码时,我按预期获得了 UI,但我无法将所有变量存储在mappe字典或result列表中。

All values are defaulted to "default" value.所有值都默认为“默认”值。 I am stuck with this one.我坚持这个。

You make a new StringVar v for every entry in features, but you don't save the previous one to later reference it.您为StringVar中的每个条目创建一个新的StringVar v ,但您不保存前一个以供以后参考。 You should make v a dictionary and save the StringVar s under the key of the feature they belong to.您应该将v设为字典并将StringVar保存在它们所属功能的键下。

Also, the command argument expects a reference to a function, but you give it a function call, which means that the return value of that function will be assigned to command .此外, command参数需要对函数的引用,但您给它一个函数调用,这意味着该函数的返回值将分配给command So instead of using command=function() , one should use command=function .因此,不应使用command=function() ,而应使用command=function Because you want to pass a variable to the function, you need the command to call a new function which calls your actual function.因为您想将一个变量传递给该函数,所以您需要该command来调用一个调用您实际函数的新函数。 Fortunately, you can do this very easily using a lambda function like幸运的是,您可以使用lambda函数轻松完成此操作,例如

command = lambda: saver(each)

However, because lambda functions are only evaluated when they are called, you need to specify that you want to use the each at that time, not the each from the last iteration.但是,由于lambda函数仅在调用时才进行计算,因此您需要指定当时要使用each ,而不是上次迭代中的each You do that using你这样做

command = lambda each=each: saver(each)

Then, for saving the input I'd recommend using the dictionary instead of the list, because you reference the items in features using their name, not their index.然后,用于保存输入我建议使用字典而不是列表,因为你在引用这些项的features使用他们的名字,而不是他们的索引。

Combining all that, your program becomes:结合所有这些,你的程序变成:

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

This tripped me up as well.这也把我绊倒了。 The interface feels inconsistent to me since the parent frames persist, but other variables passed into the factories do not.由于父框架持续存在,因此接口对我来说感觉不一致,但传递给工厂的其他变量没有。 Another workaround is to monkeypatch the parent with it.另一种解决方法是使用它来对父级进行猴子修补。 It feels like a hack, and I can't speak to how Pythonish it is, but in a way it seems very elegant.这感觉就像一个黑客,我无法谈论它是多么的 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 

This will cause the variable to persist when it didn't otherwise.这将导致变量在没有其他情况下持续存在。 Understandably, you run the risk of overriding existing variables in the Label class.可以理解,您冒着覆盖 Label 类中现有变量的风险。 However, it does eliminate the need to track variables outside the scope of where they were assigned to the label.但是,它确实消除了跟踪分配给标签的范围之外的变量的需要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM