user2497792
user2497792

Reputation: 525

Can specific child widgets of a tkinter frame object be manipulated accessing them through the parent?

I have a table of widgets which is contained inside of a frame (inside another frame but that is not important)

Which looks like:

self.myTable = Frame(self.pf) #self.pf is the frame which contains my table
Label(self.myTable, text='Amount').grid(row=0, column=0)
Label(self.myTable, text='Rate').grid(row=0, column=1)
Button(self.myTable, text='Delete').gri(row=0, column=2)
Button(self.myTable,)text='Editor').grid(row=0, column=3)

As you can see some of the widgets inside the frame(table) are Labels while others are buttons

Is there a way to manipulate only the button objects by accessing the parent? for example: change the state of only the buttons through the parent

I know this code is incorrect for several reasons, but it is essentially what I am looking to do self.myTable.CHILDRENTHATAREBUTTONS.config(state=DISABLED)

Upvotes: 1

Views: 7789

Answers (3)

Wesley Qsian
Wesley Qsian

Reputation: 41

I faced with just the same problems yesterday - here is my answer:

There's a magic function called winfo_children (rather than simply children) which can get all children of the parent widget. Here are two examples:

root = tkinter.Tk()

eg1.

for child in root.winfo_children():
    child.config(state="disable")

eg2.

frm = tkinter.Frame(root)
for child in frm.winfo_children():
    child.destroy()

Upvotes: 1

Mathieu Rollet
Mathieu Rollet

Reputation: 2374

Well you could create an attribute of your Frame object that stores a list of its children buttons.

self.myTable = Frame(self.pf)
Label(self.myTable, text='Amount').grid(row=0, column=0)
Label(self.myTable, text='Rate').grid(row=0, column=1)
rmBtn = Button(self.myTable, text='Delete')
editBtn = Button(self.myTable, text='Editor')
rmBtn.grid(row=0, column=2)
editBtn.grid(row=0, column=3)
self.myTable.buttons = [rmBtn, editBtn]

You then access them by looping on the attribute :

for btn in self.myTable.buttons:
    btn.config(state=tk.DISABLED)

However, don't abuse of monkey patching, it's always cleaner to create a derivated class of the one you want to add methods or attributes to.

class NFrame(Frame):
    def __init__(self, master):
        Frame.__init__(self, master)
        self.buttons = []

Upvotes: 0

user2540905
user2540905

Reputation: 36

See winfo_children http://effbot.org/tkinterbook/widget.htm which would also return the labels. You don't save any references to the buttons and I don't know if that is necessary or not. The following simple example appends each button instance to a list which is a straight forward way to do it.

try:
    import Tkinter as tk     ## Python 2.x
except ImportError:
    import tkinter as tk     ## Python 3.x

def callback():
    for but in button_list:
        but.config(state=tk.DISABLED)

master=tk.Tk()
table = tk.Frame(master)
tk.Label(table, text='Amount').grid(row=0, column=0)
tk.Label(table, text='Rate').grid(row=0, column=1)
table.grid()

button_list = []
but=tk.Button(table, text='Delete', command=callback)
but.grid(row=0, column=2)
button_list.append(but)
but=tk.Button(table, text='Editor', command=callback)
but.grid(row=0, column=3)
button_list.append(but)

master.mainloop()

Upvotes: 1

Related Questions