You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将tkinter Toplevel变量传入另一类的Treeview并解决报错?

解决Tkinter Toplevel传值到根应用Treeview的AttributeError问题

这个问题我做点餐类系统时也碰到过,核心是你搞混了类和实例的区别,导致访问不到coTree这个实例属性。先给你拆解下错误根源,再给两种实操性强的修复方案:

错误原因分析

你代码里用PoS.add_custom_item(PoS,PoS.custom_item)直接通过类名调用实例方法,还把PoS类本身当作self参数传进去——但coTree是PoS类实例化后才会有的属性,类本身根本没有这个属性,自然会抛出AttributeError: type object 'PoS' has no attribute 'coTree'。

后来你试的addItem = PoS.add_custom_item(self,self.custom_item)也无效,是因为这里的self是Toplevel窗口的实例(比如你的自定义披萨窗口类的实例),不是PoS根应用的实例,方法里的self.coTree会去查找Toplevel实例的属性,当然也找不到。

修复方案一:给Toplevel传递PoS实例引用

这是最直观的方式,在打开自定义披萨窗口时,把PoS的实例传进去,让Toplevel能直接调用根应用的方法:

1. 修改PoS类中打开Toplevel的代码

假设你在PoS类里有打开自定义披萨窗口的方法,把自身实例传进去:

class PoS:
    def __init__(self, root):
        self.root = root
        # 初始化你的结账Treeview
        self.coTree = ttk.Treeview(root, columns=("Name", "Price"), show="headings")
        # ...其他初始化代码

    def open_custom_pizza(self):
        # 把PoS实例self传给自定义窗口
        CustomPizzaWindow(pos_instance=self)

2. 修改自定义披萨窗口类

在窗口初始化时保存PoS实例,提交时直接调用实例的add_custom_item方法:

class CustomPizzaWindow:
    def __init__(self, pos_instance):
        self.pos_instance = pos_instance  # 保存根应用实例
        self.win = tk.Toplevel()
        # ...窗口内的控件初始化(比如配料选择、价格计算等)

    def submit(self):
        # 构建自定义披萨的Item对象
        name = "自定义披萨"  # 替换成你实际的名称逻辑
        self.total = 19.99  # 替换成你实际的总价计算逻辑
        self.custom_item = Item(000, name, self.total, 'Pizza')
        
        # 调用PoS实例的方法,直接传入Item对象
        self.pos_instance.add_custom_item(self.custom_item)
        self.win.destroy()

3. 修正PoS类的add_custom_item方法

保持它是正常的实例方法,直接使用自身的coTree属性:

class PoS:
    # ...其他代码
    def add_custom_item(self, item):
        # 直接用实例的coTree插入数据
        self.coTree.insert('', 'end', text='1', open=True, values=(item.name, '{:.2f}'.format(item.price)))

修复方案二:使用回调函数解耦

如果你不想让Toplevel持有整个PoS实例,可以把add_custom_item方法作为回调函数传递过去,更符合解耦设计:

1. 修改PoS类打开窗口的代码

class PoS:
    # ...其他代码
    def open_custom_pizza(self):
        # 把add_custom_item方法作为回调传给窗口
        CustomPizzaWindow(on_submit=self.add_custom_item)

2. 修改自定义披萨窗口类

class CustomPizzaWindow:
    def __init__(self, on_submit):
        self.on_submit = on_submit  # 保存回调函数
        self.win = tk.Toplevel()
        # ...窗口内的控件初始化

    def submit(self):
        # 构建Item对象逻辑同上
        self.custom_item = Item(000, name, self.total, 'Pizza')
        # 调用回调函数,传入Item对象
        self.on_submit(self.custom_item)
        self.win.destroy()

3. PoS类的add_custom_item方法无需修改

和方案一里的方法保持一致即可。

这两种方案都能解决你的问题,方案一适合简单的小项目,方案二更适合复杂项目的解耦需求。

内容的提问来源于stack exchange,提问作者maxxslatt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 20:07:41