首页 > 解决方案 > tkinter 小部件从另一个小部件调用方法

问题描述

在开发 tkinter 应用程序(Tcl/Tk 8.6 和 Python 3.9.2)时,我最近遇到了一个我能够解决的错误,但我认为该错误的存在突出了我的知识差距和我的方法中的潜在弱点。

下面是一个可重现的错误示例 - 此代码将不起作用并返回错误AttributeError: 'parent_class' object has no attribute 'first'

from tkinter import *
from tkinter import ttk

class child_one(ttk.Frame):
    def __init__(self, parent, **kwargs):
        super().__init__(parent, **kwargs)
        self.x = 10

    def print_x(self):
        print(self.x)

class child_two(ttk.Frame):
    def __init__(self, parent, **kwargs):
        super().__init__(parent, **kwargs)
        self.b = ttk.Button(self, text='Button 1',
                            command=parent.first.print_x).grid()

class parent_class(ttk.Frame):
    def __init__(self, parent, **kwargs):
        super().__init__(parent, **kwargs)
        self.grid()

        self.second = child_two(self)
        self.first = child_one(self)

        self.first.grid()
        self.second.grid()

if __name__ == '__main__':
    root = Tk()
    w = parent_class(root)
    root.mainloop()

但是,如果我颠倒创建child_one和的实例的顺序,child_two即替换

        self.second = child_two(self)
        self.first = child_one(self)

        self.first = child_one(self)
        self.second = child_two(self)

在 的定义中parent_class

我真的很感谢任何解释或资源链接,以帮助我理解导致这种情况发生的程序流程 - 在我看来,当我创建w并到达行self.second = child_two(self)Python 只是查看实例的一部分parent_class时已经创建,而不是类的整个定义。

如果这不是parent_class要创建的第一个实例,会发生这种情况吗?它是 tkinter 特有的吗?(我只能使用 tkinter 小部件创建一个简单的可重现示例,而不是更一般地使用类。)

我想另一种解决方案是制作print_x一个(静态?)方法parent_class?我还假设这里没有足够的细节来明确说明(或替代结构)是否更适合促进我的应用程序组件之间的接口,但有兴趣听到有关该领域良好实践的任何建议。

标签: pythontkinter

解决方案


当您说“Python 只是查看已创建的 parent_class 实例的一部分,而不是类的整个定义时,您似乎期望 python 在程序之前构建了您的类的静态描述开始运行。

Python 不是这样工作的,它是一种动态语言。正如 Bryan 刚才所说,该first变量仅在您第一次分配给它时才会创建。


推荐阅读