python - 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
?我还假设这里没有足够的细节来明确说明(或替代结构)是否更适合促进我的应用程序组件之间的接口,但有兴趣听到有关该领域良好实践的任何建议。
解决方案
当您说“Python 只是查看已创建的 parent_class 实例的一部分,而不是类的整个定义”时,您似乎期望 python 在程序之前构建了您的类的静态描述开始运行。
Python 不是这样工作的,它是一种动态语言。正如 Bryan 刚才所说,该first
变量仅在您第一次分配给它时才会创建。
推荐阅读
- react-native - 运行时类型错误:hmrClient.send 不是函数
- api - Nuxt 重新加载 api 数据失败
- swift - 从自定义 .plist 文件中读取用户定义的设置
- botframework - Microsoft Bot framework v4 中消息的跨平台文本格式和 UI 设计
- node.js - 如何在另一台机器上运行节点应用程序而不安装 nodemon 作为全局
- html - CSS中图像的文件路径
- typescript - 当泛型类型设置为从不时,泛型条件类型解析为从不
- python-3.x - 没有循环if语句的for循环
- modelica - 替换 Modelica 中已弃用的函数基数(c)
- install4j - Windows 系统上 error.log 文件的位置