user1530213
user1530213

Reputation: 111

How would you retrieve values from iteratively created checkboxes?

I'm trying to get Tkinter checkbox values from iteratively created checkboxes. I cannot fathom how to reference the associated variable for each/any of these checkboxes from outside the __init__ function. Here is the relevant code:

class Display_Window():
    def __init__(self, parent):
# some code excluded here
        self.widgets = []
        for i in range(len(self.eventNameList)): # a list of dictionaries
            self.eventName = self.eventNameList[i]['event_name']
            self.var1 = IntVar()
            self.cbEvent = Checkbutton(self.myContainer, text=self.eventName,
                                                            variable=self.var1)
            self.cbEvent.grid(row = i+2, column = 0, sticky = W)
            self.cbEvent.deselect()
            self.widgets.append((self.eventName, self.cbEvent)

        self.bSelect = Button(self.myContainer, text="Select", width=10)
        self.bSelect.bind("<Button-1>",
                             lambda event, arg=self.widgets: self.select(arg))
        self.bSelect.bind("<Return>",
                             lambda event, arg=self.widgets: self.select(arg))
        self.bSelect.grid(row = 1, column = 2)

    def select(self, widgets):
        for widget in widgets:
            cBox = widget[1] # references the checkbox
            cBoxValue = #get() what?

Upvotes: 0

Views: 570

Answers (1)

jdi
jdi

Reputation: 92569

The creation of your dynamic number of check buttons doesn't (and shouldn't) assign them as attributes of the instance. What you are doing is simply leaving the last one created as member attributes, which is pretty pointless.

Also, you almost have the correct idea with your list of widgets...

class Display_Window():
    def __init__(self, parent):
...snip...

        self.widgets = {}

        for i, eventDict in enumerate(self.eventNameList):        
            eventName = eventDict['event_name']
            var1 = IntVar()
            cbEvent = Checkbutton(self.myContainer, text=eventName, variable=var1) 
            cbEvent.grid(row = i+2, column = 0, sticky = W)
            cbEvent.deselect()

            self.widgets[eventName] = (cbEvent, var1)

        self.bSelect = Button(self.myContainer, text="Select", width=10)
        self.bSelect.bind("<Button-1>", self.select)
        self.bSelect.bind("<Return>", self.select)
        self.bSelect.grid(row = 1, column = 2)

    def select(self, *args):
        for widget, intvar in self.widgets.iteritems():
            # do stuff

What you could do, as in my example above, is store the check buttons in a dict, assuming that the event names are unique. This would make them easy to look up by name instead of looping over a list. And in that dict, I am storing a tuple, where the first item is the widget, and the second is the IntVar. I am not sure how you really wanted to organize it, but that is one way to save those references.

Also, it seems you no longer need to do a custom lambda for the callback of the button to pass the reference, since select is a member of the same class, It can simply look at the self.widgets dict.

Upvotes: 1

Related Questions