在python的tkinter中访问父类(不完全是)的函数和变量

问题描述 投票:0回答:1

请参阅下面我从 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()
    

如果我的理解有误,请指正。
我认为 Table 对象被 Application 对象使用。
我在标题中添加了“不完全”,因为表和应用程序分别不是子项和父项。不是吗?
应用程序对象中有一个变量“total”。
您可以假设“总计”也受到应用程序中其他小部件的影响,我没有显示这些小部件,因为这与这个问题无关。
我的目标是根据表中的数量列更新“总计”。因此,当条目添加到表中时,应该更新总计,并且必须从 add_row 内部调用 show_total 函数。 del_row 中的情况也是如此。
另请注意,可以通过单击表中我未显示的按钮来调用 del_row (实际上,每一行中都有一个删除按钮,为了保持代码简短,我未显示该按钮)。 这怎么办?
谢谢。

python tkinter
1个回答
0
投票

在 Application 类中,您可以通过传递

Table
:
 创建 
self

的实例
self.table = Table(self, header_labels)

这意味着Table的

master
方法中的
__init__
参数是
Application
的实例。 因此,更新 Table 类如下:

在Table的

__init__
方法中,添加:

self.master = master

add_row

self.master.total += quantity
self.master.show_total()
© www.soinside.com 2019 - 2024. All rights reserved.