Please see the code below I got from OysterShucker
import tkinter as tk
class Table(tk.Frame):
def __init__(self, master, header_labels:tuple, *args, **kwargs):
tk.Frame.__init__(self, master, *args, **kwargs)
# configuration for all Labels
# easier to maintain than directly inputting args
self.lbl_cfg = {
'master' : self,
'foreground' : 'blue',
'relief' : 'raised',
'font' : 'Arial 16 bold',
'padx' : 0,
'pady' : 0,
'borderwidth': 1,
'width' : 11,
}
self.headers = []
self.rows = []
for col, lbl in enumerate(header_labels):
self.grid_columnconfigure(col, weight=1)
# make and store header
(header := tk.Label(text=lbl, **self.lbl_cfg)).grid(row=0, column=col, sticky='nswe')
self.headers.append(header)
def add_row(self, desc:str, quantity:int, rate:float, amt:float, pending:bool) -> None:
print("how can I update variable total and call show_total")
self.rows.append([])
for col, lbl in enumerate((desc, quantity, rate, amt, pending), 1):
(entry := tk.Label(text=lbl, **self.lbl_cfg)).grid(row=len(self.rows), column=col, sticky='nswe')
self.rows[-1].append(entry)
def del_row(self, i:int) -> None:
for ent in self.rows[i]:
ent.destroy()
del self.rows[i]
for r, row in enumerate(self.rows, 1):
for c, ent in enumerate(row, 1):
ent.grid_forget()
ent.grid(row=r, column=c, sticky='nswe')
class Application(tk.Tk):
def __init__(self, title:str="Sample Application", x:int=0, y:int=0, **kwargs):
tk.Tk.__init__(self)
self.title(title)
self.config(**kwargs)
header_labels = ('', 'Description', 'Quantity', 'Rate', 'Amt', 'pending')
self.total=0
self.table = Table(self, header_labels)
self.table.grid(row=0, column=0, sticky='nswe')
# update so we can get the current dimensions
self.update_idletasks()
self.geometry(f'{self.winfo_width()}x{self["height"] or self.winfo_screenheight()}+{x}+{y}')
# test
self.table.add_row("A", 2, 12.5, 25, True)
self.table.add_row("B", 4, 12.5, 50, False)
self.table.del_row(0)
self.table.add_row("A", 2, 12.5, 25, True)
def show_total(self):
print(self.total)
print("Total has been updated")
return
if __name__ == "__main__":
# height of 0 defaults to screenheight, else use height
Application(title="My Application", height=0).mainloop()
Please correct me if my understanding is wrong.
I think Table object is used by Application object.
I have put 'not exactly' in title because Table and Application are not child and parent respectively. Isn't it ?
There is a variable 'total' in Application object.
You can assume that 'total' is also affected by other widgets in Application which I have not shown because that will not be relevant to this question.
My aim is to update 'total' according to Quantity column in table . So, when entry is added to table then total should be updated and show_total function has to be called from inside add_row. Same will be case in del_row.
Also note that del_row can be called by clicking of a button inside table which I have not shown (actually, there is a delete button in every row which I have not shown to keep code short).
How can this be done ?
Thanks.
In the Application class, you create an instance of Table
by passing self
:
self.table = Table(self, header_labels)
This means that the master
parameter in the __init__
method of Table is an instance of Application
.
So, update the Table class as follows:
in the __init__
method of Table, add:
self.master = master
in add_row
self.master.total += quantity
self.master.show_total()
similarly you modify del_row
as needed