如何在Python Kivy弹窗中调用RelativeLayout类的方法?
问题描述
点击弹窗按钮尝试调用MainLayout类的print_hello方法时,出现以下错误:
on_press: root.print_hello() File "kivy/weakproxy.pyx", line 32, in kivy.weakproxy.WeakProxy.__getattr__ AttributeError: 'PopupMenu' object has no attribute 'print_hello'
Python文件代码:
#!/usr/bin/env python3 from kivy.app import App from kivy.factory import Factory from kivy.uix.relativelayout import RelativeLayout class MainLayout(RelativeLayout): def __init__(self, **kwargs): super(MainLayout, self).__init__(**kwargs) self.data = "Important data from the MainLayout class" def print_hello(self): print("Hello") class MyApp(App): # defining the app class def build(self): # using MyRelativeLayout in the app return MainLayout() # returning MyRelativeLayout MyApp().run()
Kv文件代码:
#:import Factory kivy.factory.Factory <MainLayout>: Button: text: "Main Button" pos_hint: {"x": 0, "top": 1} on_press: Factory.PopupMenu().open() <PopupMenu@Popup> auto_dismiss: True title: "Popup Menu" size_hint: [0.80, 0.80] pos_hint: {"center_x": 0.5, "center_y": 0.5} RelativeLayout: size_hint: [1, 1] pos_hint: {"x": 0, "top": 1} PopupWindowButton: id: line_button size_hint: [0.10, 0.10 * root.width / root.height] pos_hint: {"x": 0, "top": 1} text: "Popup Button" on_press: root.print_hello() <PopupWindowButton@Button> font_size: "15dp" background_color: 0, 0.5, 0, 1
需求:通过点击弹窗按钮调用MainLayout类的print_hello方法。
解决方案
方法1:传递MainLayout实例给弹窗
打开弹窗时将当前MainLayout实例传入弹窗,通过引用调用目标方法。
修改Kv文件的MainLayout部分:
<MainLayout>: Button: text: "Main Button" pos_hint: {"x": 0, "top": 1} on_press: popup = Factory.PopupMenu() popup.main_layout = root # 传递MainLayout实例 popup.open()
修改Kv文件的PopupMenu部分:
<PopupMenu@Popup> main_layout: None # 定义属性存储MainLayout实例 auto_dismiss: True title: "Popup Menu" size_hint: [0.80, 0.80] pos_hint: {"center_x": 0.5, "center_y": 0.5} RelativeLayout: size_hint: [1, 1] pos_hint: {"x": 0, "top": 1} PopupWindowButton: id: line_button size_hint: [0.10, 0.10 * root.width / root.height] pos_hint: {"x": 0, "top": 1} text: "Popup Button" on_press: root.main_layout.print_hello() # 通过引用调用方法
方法2:通过App实例获取根布局
利用Kivy的app全局变量直接获取根布局(即MainLayout实例),适合全局调用场景。
修改Kv文件的Popup按钮事件:
<PopupMenu@Popup> auto_dismiss: True title: "Popup Menu" size_hint: [0.80, 0.80] pos_hint: {"center_x": 0.5, "center_y": 0.5} RelativeLayout: size_hint: [1, 1] pos_hint: {"x": 0, "top": 1} PopupWindowButton: id: line_button size_hint: [0.10, 0.10 * root.width / root.height] pos_hint: {"x": 0, "top": 1} text: "Popup Button" on_press: app.root.print_hello() # app代表当前App实例,root为根布局
此方法无需修改Python代码,仅调整Kv文件即可。
方法3:Python代码中绑定弹窗事件
在MainLayout类中封装弹窗逻辑,直接绑定按钮事件到目标方法。
修改Python文件的MainLayout类:
class MainLayout(RelativeLayout): def __init__(self, **kwargs): super(MainLayout, self).__init__(**kwargs) self.data = "Important data from the MainLayout class" def print_hello(self): print("Hello") def open_popup(self): popup = Factory.PopupMenu() # 绑定按钮点击事件到print_hello方法 popup.ids.line_button.bind(on_press=lambda x: self.print_hello()) popup.open()
修改Kv文件的MainLayout按钮事件:
<MainLayout>: Button: text: "Main Button" pos_hint: {"x": 0, "top": 1} on_press: root.open_popup()
同时移除PopupMenu中按钮的原有on_press事件:
<PopupMenu@Popup> auto_dismiss: True title: "Popup Menu" size_hint: [0.80, 0.80] pos_hint: {"center_x": 0.5, "center_y": 0.5} RelativeLayout: size_hint: [1, 1] pos_hint: {"x": 0, "top": 1} PopupWindowButton: id: line_button size_hint: [0.10, 0.10 * root.width / root.height] pos_hint: {"x": 0, "top": 1} text: "Popup Button"
内容的提问来源于stack exchange,提问作者MFPM
相关产品推荐
相关产品推荐

