2

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")
David W. Beck
  • 182
  • 1
  • 9
  • 1
    If I understand correctly what you want, you just have to create a list in your class and make a function which create your widget and add it to this list – Stephie Nov 17 '17 at 10:13
  • You could at the very least select all objects, recursively assuming `winfo_children` works the way you say. – Nae Nov 17 '17 at 10:18
  • 1
    Are you unable to create the widgets as in a list of widget objects, like `for i in range(10): btn[i] = tk.Button(parent, text="button" + num)`? – Nae Nov 17 '17 at 10:51

1 Answers1

4

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()
Ethan Field
  • 4,646
  • 3
  • 22
  • 43