David  W. Beck
David W. Beck

Reputation: 192

Adding all the tk.Button objects to a list to config

So I'd like to add all the tk.Button(and entry) objects in an entire program to a list. (so that I can change the colours of every button though iterate and config)

I'm creating a bunch of tkinter frames like this:

class AppClass(tk.Tk):

    def __init__(self, *args, **kwargs):


        # Initialising Tkinter
        tk.Tk.__init__(self, *args, **kwargs)
        tk.Tk.wm_title(self, 'test-program')
        tk.Tk.geometry(self, '800x480') 

        container = tk.Frame(self)
        container.pack(fill='both', expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.background_theme = '2'
        self.background_theme_to_be_written_to_file  = '2'

        self.frames = {}

        for F in (HomePage,
                  SecondName,
                  ThirdName):

            frame = F(container, self)


            self.frames[F] = frame

            frame.grid(row=0, column=0, sticky="nsew")

            frame.configure(background=background_page)


        self.show_frame(HomePage)

...

app = AppClass()

app.mainloop()
app = None
exit()

Ideas? I know .winfo_children() can select all the objects in a page - can we select all the objects in the program?

**

at the moment I'm trying to make something like this work - oddly it's only changing one button on the screen (There are 4):

parent.list_of_objects_in_parent = tk.Button.winfo_children(parent)

print(parent.list_of_objects_in_parent)

for entry in parent.list_of_objects_in_parent:
    entry.config(bg="pink")

**quick update:

I kind of have a partial solution:

self.bind("<<ShowFrame>>", self.on_show_frame)

...

def on_show_frame(self, event):
    self.list_of_objects_in_parent = tk.Button.winfo_children(self)
    print(self.list_of_objects_in_parent)
    for entry in self.list_of_objects_in_parent:
        if type(entry) == type(self.button_to_go_to_home_page):
            entry.config(bg="pink")
            print("working")

Upvotes: 2

Views: 403

Answers (1)

Ethan Field
Ethan Field

Reputation: 4730

Yes, this is possible.

You can simply call .winfo_children() on the Tk() window which will return a list of all widgets in the top level of the window which you can iterate over, see below:

from tkinter import *

root = Tk()

def command():
    for i in root.winfo_children():
        i.configure(bg="pink")

entry = Entry(root)
button = Button(root, text="Ok", command=command)

entry.pack()
button.pack()

root.mainloop()

If you have multiple layers of widgets (IE, Frames containing widgets, Toplevel widgets) then you need to add some sort of recursion in order to get ALL of the widgets in your program, we can do this with something like the below:

from tkinter import *

root = Tk()

def command():
    x = root.winfo_children()
    for i in x:
        if i.winfo_children():
            x.extend(i.winfo_children())
        i.configure(bg="pink")

entry = Entry(root)
button = Button(root, text="Ok", command=command)

frame = Frame(root)
entry2 = Entry(frame)

top = Toplevel(root)
entry3 = Entry(top)

entry.pack()
entry2.pack()
entry3.pack()
button.pack()
frame.pack()

root.mainloop()

Upvotes: 4

Related Questions