Kivy使用类方法关闭Popup弹窗的代码问题排查与优化方案
现有代码的核心问题
- 事件绑定逻辑错误:你在给
btn2绑定on_press回调时,写了self.on_exit_press()带了括号,这会直接执行on_exit_press方法,而不是把方法本身作为回调函数传递给点击事件,按钮点击时不会触发你要的逻辑。 - 弹窗实例未存储为实例属性:
popup_window1是on_button_press1方法内的局部变量,方法执行完之后这个变量就被回收了,你没有把它赋值给self.popup_window1,所以on_exit_press里访问self.popup_window1会直接抛出属性不存在的报错。
修复后的参考代码
class AnchorLayoutExample(AnchorLayout): def make_content(self): layout = BoxLayout(orientation='vertical') text1 = TextInput(text='Insert Name', multiline=False, size_hint=(1, .2)) text2 = TextInput(text='Insert Charge', multiline=False, size_hint=(1, .2)) btn1 = Button(text='Send') btn2 = Button(text='Exit') # 绑定回调不要加括号 btn2.bind(on_press=self.on_exit_press) layout.add_widget(text1) layout.add_widget(text2) layout.add_widget(btn1) layout.add_widget(btn2) return layout def on_button_press1(self): show = self.make_content() # 把弹窗实例存为实例属性,其他方法才能访问 self.popup_window1 = Popup(title="Insert new expense", content=show, size_hint=(.9, .9)) self.popup_window1.open() def on_exit_press(self, instance): # Kivy事件回调会默认传递触发事件的组件实例作为第一个参数,要加上参数接收 self.popup_window1.dismiss()
更优实现方式
如果不想额外存储弹窗实例,可以直接在创建内容的时候把弹窗实例传给退出按钮的回调,避免占用实例属性,降低逻辑耦合度:
from functools import partial class AnchorLayoutExample(AnchorLayout): def make_content(self, popup): layout = BoxLayout(orientation='vertical') text1 = TextInput(text='Insert Name', multiline=False, size_hint=(1, .2)) text2 = TextInput(text='Insert Charge', multiline=False, size_hint=(1, .2)) btn1 = Button(text='Send') btn2 = Button(text='Exit') # 用partial直接把弹窗实例传给关闭方法 btn2.bind(on_press=partial(self.on_exit_press, popup)) layout.add_widget(text1) layout.add_widget(text2) layout.add_widget(btn1) layout.add_widget(btn2) return layout def on_button_press1(self): popup_window1 = Popup(title="Insert new expense", content=None, size_hint=(.9, .9)) # 先创建弹窗实例,再把实例传给make_content生成内容 popup_window1.content = self.make_content(popup_window1) popup_window1.open() def on_exit_press(self, popup, instance): popup.dismiss()
内容的提问来源于stack exchange,提问作者Bar Kadosh
相关产品推荐
相关产品推荐

