Kivy嵌套布局中按钮调用父类方法报错问题咨询
Kivy按钮调用方法报错问题解决
问题描述
我在info_options.kv的StackLayout中创建了一个按钮,希望点击时调用InfoOptionsPanel类的on_press方法。直接让App返回InfoOptionsPanel()时功能正常,但改用MainPanel作为GUI根组件后,点击按钮会抛出AttributeError,不过GUI显示正常。
报错信息
File "C:\Users\..\AppData\Local\Programs\Python\Python312\Lib\site-packages\kivy\lang\builder.py", line 60, in custom_callback exec(__kvlang__.co_value, idmap) File "K:\path\to\project\Info_options.kv", line 5, in <module> on_press: self.parent.on_press() ^^^^^^^^^^^^^^^^ AttributeError: 'InfoOptionsPanel' object has no attribute 'on_press'
相关文件内容
info.kv
<InfoPanel@BoxLayout> orientation: 'vertical' size_hint_y: 0.8 pos_hint: {"top": 1} Label: id: info_label text:"Click button" font_size:50
info_options.kv
<InfoOptionsPanel@StackLayout>: orientation: 'lr-tb' Button: text: 'Button' on_press: self.parent.on_press() size_hint :.7, 0.1
main_screen.kv
<MainPanel@BoxLayout>: orientation: 'vertical' AnchorLayout: anchor_x: 'left' anchor_y: 'top' InfoPanel: size: 100, 100 AnchorLayout: anchor_x: 'right' anchor_y: 'bottom' InfoOptionsPanel: size: 100, 100
main.py
from kivy.app import App from kivy.lang.builder import Builder from kivy.uix.boxlayout import BoxLayout from kivy.uix.stacklayout import StackLayout import os kivy_design_files = ["Info_options", "Info", "main_screen",] for kv_file in kivy_design_files: Builder.load_file(os.path.join(os.path.abspath(os.getcwd()), kv_file + ".kv")) class InfoPanel(BoxLayout): pass class InfoOptionsPanel(StackLayout): def on_press(self): print("Button pressed\n"*55) class MainPanel(BoxLayout): pass class MyApp(App): def build(self): return MainPanel() if __name__ == '__main__': MyApp().run()
解决方案
问题根源在于KV文件中使用@符号创建的类与Python代码中定义的同名类冲突:
在KV文件中,
<ClassName@Widget>语法是直接创建一个继承自对应组件的新类;而你已经在Python代码中定义了同名的InfoOptionsPanel和InfoPanel类,此时KV创建的类会覆盖Python中的类,导致实例化的组件没有Python类中定义的on_press方法。解决步骤:
- 修改
info_options.kv,将类定义从<InfoOptionsPanel@StackLayout>改为<InfoOptionsPanel>:<InfoOptionsPanel>: orientation: 'lr-tb' Button: text: 'Button' on_press: self.parent.on_press() size_hint :.7, 0.1 - 同理修改
info.kv,将<InfoPanel@BoxLayout>改为<InfoPanel>:<InfoPanel>: orientation: 'vertical' size_hint_y: 0.8 pos_hint: {"top": 1} Label: id: info_label text:"Click button" font_size:50 main_screen.kv中的<MainPanel@BoxLayout>可以保留,因为Python中的MainPanel类没有额外方法,或者也可以改为<MainPanel>保持规则统一。
- 修改
修改后,KV文件会直接为Python中已定义的类应用布局规则,此时点击按钮就能正常调用InfoOptionsPanel的on_press方法了。
内容的提问来源于stack exchange,提问作者Aman
相关产品推荐
相关产品推荐

