Kivy中kv事件回调实例化类报NameError的原因咨询
问题原因及解决方法
你遇到的NameError本质是KV语言中Python表达式的命名空间限制,具体原因和解决方法如下:
1. KV声明组件与Python表达式的执行逻辑差异
- 当你在KV里直接写
MyButton:时,这是KV的声明式语法,Kivy会自动在全局已注册的Widget类中查找MyButton(你在Python代码中定义的类会被自动注册到Kivy内部的Factory),因此能正常创建实例。 - 但在
on_parent的Python代码块里(for i in range(1,3): self.add_widget(MyButton(...))),这段代码是作为Python表达式执行的,它的运行上下文只能直接访问root(根部件实例)、self(当前部件实例)、app(应用实例)这几个内置变量,无法直接读取全局命名空间中的MyButton类,所以会抛出NameError。
2. root.MyButton2正常工作的原因
MyButton2是MainWidget的内部类,而root指向MainWidget的实例,通过root.MyButton2可以直接访问到这个内部类,它属于root实例的可访问命名空间,因此Python表达式能找到并实例化它。
正确解决方法(无需内部类)
你不需要额外定义MyButton2,直接通过Kivy的Factory模块在KV表达式中引用MyButton即可——所有Widget类都会自动注册到Factory中。
修改后的KV代码示例:
#:import Factory kivy.factory.Factory <MyButton>: <MainWidget>: BoxLayout: on_parent: for i in range(1,3): self.add_widget(Factory.MyButton(text = str(i), pos=self.pos)) MyButton: text: '1'
这样就能直接使用全局定义的MyButton类,无需内部类中转。
内容的提问来源于stack exchange,提问作者Eugene B
相关产品推荐
相关产品推荐

