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

如何关闭Kivy中由外部函数创建的Popup弹窗

解决Kivy驱动器Popup关闭问题

问题描述

我正在做一个Kivy Popup用来显示所有可用驱动器,需求是点击驱动器按钮后,在FileChooser组件中打开对应目录。现在遇到的问题是:打开目录后需要关闭这个驱动器Popup,但在get_drive函数里没法引用到这个Popup;我试过在类顶部创建Popup,也没解决问题。

原代码

def filebtn(self):

    global popup
    from functools import partial

    popup_1 = Popup(title="Select drive to access", size_hint=(0.7, 0.7))
    content_layout = BoxLayout(orientation='vertical', spacing=10)
    box_layout = BoxLayout(size=(500, 500))

    if platform == 'win':

        print('platform is windows')

        drives = []
        for letter in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
            drive_path = f"{letter}:\\"
            if os.path.exists(drive_path):
                drives.append(drive_path)
        print(drives)

        for item in drives:
            btn = Button(text=item)
            btn.bind(on_release=partial(self.get_drive, item))

            content_layout.add_widget(btn)

        popup_1.add_widget(content_layout)

        popup_1.open()

    else:
        popup.open()

def get_drive(self,item,instance):

    print(f"Button text: {item}")
    MyFileChooser.rootpath = item

    popup = Popup(title='Select Files and click attach when selected, click outside the box to close',
                  content=MyFileChooser(),
                  # dont need () because they already called the function at the top of class with mc = Myfilechooser()
                  size_hint=(0.7, 0.7))
    popup.bind(on_dismiss=lambda attached: self.attach_called())


    popup.open()
    popup_1.dismiss() # problem here

解决方案

问题根源是popup_1是filebtn函数内的局部变量,get_drive函数无法直接访问它。解决办法是通过partial把popup_1作为参数传递给get_drive:

修改后的代码

def filebtn(self):

    from functools import partial  # 建议把导入放在文件顶部,不要放函数里

    popup_1 = Popup(title="Select drive to access", size_hint=(0.7, 0.7))
    content_layout = BoxLayout(orientation='vertical', spacing=10)
    box_layout = BoxLayout(size=(500, 500))

    if platform == 'win':

        print('platform is windows')

        drives = []
        for letter in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
            drive_path = f"{letter}:\\"
            if os.path.exists(drive_path):
                drives.append(drive_path)
        print(drives)

        for item in drives:
            btn = Button(text=item)
            # 把popup_1也作为参数传递给get_drive
            btn.bind(on_release=partial(self.get_drive, item, popup_1))

            content_layout.add_widget(btn)

        popup_1.add_widget(content_layout)

        popup_1.open()

    else:
        # 注意这里的popup需要提前定义,否则会报错
        popup.open()

def get_drive(self, item, popup_1, instance):
    # 参数顺序调整:先item,再popup_1,最后是按钮实例

    print(f"Button text: {item}")
    MyFileChooser.rootpath = item

    popup = Popup(title='Select Files and click attach when selected, click outside the box to close',
                  content=MyFileChooser(),
                  size_hint=(0.7, 0.7))
    popup.bind(on_dismiss=lambda attached: self.attach_called())

    popup.open()
    popup_1.dismiss()  # 现在可以正常引用并关闭驱动器Popup了

关键修改点

  1. 在filebtn中,绑定按钮事件时,通过partial把popup_1作为额外参数传递给get_drive
  2. 调整get_drive的参数列表,新增popup_1参数,确保参数顺序和partial传递的一致
  3. 移除了不必要的global popup声明(如果popup在其他地方定义,确保它的作用域正确)

内容的提问来源于stack exchange,提问作者Foton

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 10:16:17