You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 21:54:03