1

So I'm trying to use a for loop to create multiple check buttons in Tkinter by iterating over a nested list with the text that I want to display and its variable.

The reason that I'm trying to automate this is that I may want to change the number of check buttons that I have in the future, so I thought it would be easier incorporating it in a list (that I can change later) instead of doing it manually. Here's what I've tried:

from tkinter import *

class Application(Frame):

    def __init__(self, master):
        super(Application, self).__init__(master)
        self.grid()
        self.create_widgets()

    def create_widgets(self):
        checkbttn_info = \ # nested list
        [("General Purposes", self.general_purposes),
        ("Young People",self.young_people),
        ("Education And Learning", self.education_and_learning),
        ("Healthcare Sector",self.healthcare_sector),
        ("Arts Or Heritage", self.arts_or_heritage),
        ("Infrastructure Support", self.infrastructure_support)
        ("Regenerating Areas", self.regenerating_areas)
        ("Community Cohesion", self.community_cohesion)]

        row, col = 2, 0
        for variable in checkbttn_info:
            variable[1] = BooleanVar()
            Checkbutton(self,
                    variable = variable[1],
                    text = variable[0]).grid(row = row, column = col, sticky = W)
            if col == 2:
               col = 0
               row +=1
            else:
               col +=1

Unfortunately, I get the exception:

AttributeError: 'Application' object has no attribute 'general_purposes'

I think I understand why this is but I don't know how to fix it. The Application object doesn't have any 'general_purposes' attribute because I haven't instantiated it with the BooleanVar() object, however, no other way to do it springs to mind apart from above. I try to instantiate it within the for loop but it obviously doesn't work...

Is there a way to fix the exception or a better way to do it overall? Thanks in advance for any suggestions!

1 Answer 1

1

The most obvious solution I can see is to make a list of names (["General Purposes", "Young People", ...]) and use the list in the for loop. Then let the loop create the variables and add them to a dict with the names as keys and the variables as values;

from tkinter import *

class Application(Frame):

    def __init__(self, master):
        super(Application, self).__init__(master)
        self.grid()
        self.create_widgets()

    def create_widgets(self):
        name_list = ["General Purposes", "Young People",
                     "Education And Learning", "Healthcare Sector",
                     "Arts Or Heritage", "Infrastructure Support",
                     "Regenerating Areas", "Community Cohesion"]

        row, col = 2, 0
        widget_dict = {}
        for name in name_list:
            variable = BooleanVar()
            c = Checkbutton(self, variable=variable, text=name)
            c.grid(row = row, column = col, sticky = W)
            widget_dict[name] = variable
            if col == 2:
               col = 0
               row +=1
            else:
               col +=1

root = Tk()
app = Application(root)
root.mainloop()

If you want to keep it as simple as possible you can just declare them all in the create_widgets() function before you add them to the checkbttn_info list.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! That works perfectly. Do you mind explaining why it's important to store them in a dictionary?
The dictionary allows me to associate the variable with a value I can search for: the key. If I don't mind having several lists I can store the values in a list as well and locate the index by searching the name_list. Once I have the dict or a couple of lists it's easy to convert to a list of tuples or other format if you want that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.