Kivy中Popup弹窗无法通过按钮关闭的问题求助
解决Kivy弹窗无法通过按钮关闭的问题
问题根源
你代码中on_release:Factory.MyPopup().dismiss()的逻辑错误:每次调用Factory.MyPopup()都会生成一个全新的Popup实例,而不是操作当前正在显示的弹窗,因此点击按钮没有任何响应。
修复方案
方案1:直接修改KV语言实现关闭
修改<FileWidget>中的按钮事件,通过组件层级引用当前弹窗:
<FileWidget>: FileChooserIconView: id: filechooser dirselect: True # 强制设置为选择文件夹模式 Button: id:my_button text: 'Save' size_hint: (0.1, 0.1) pos_hint:{'x': 0, 'y': 0} on_release: # 打印选中的文件夹路径,可替换为你的业务逻辑 print(root.ids.filechooser.path) # root是FileWidget实例,其父组件就是当前打开的MyPopup root.parent.dismiss()
方案2:结合Python代码实现更灵活的逻辑
如果需要后续处理选中的文件夹路径,推荐在Python类中封装方法:
修改后的Python代码
from kivy.app import App from kivy.uix.boxlayout import BoxLayout from kivy.uix.floatlayout import FloatLayout from kivy.uix.popup import Popup class MyPopup(Popup): pass class FloatLayout1(FloatLayout): pass class FileWidget(FloatLayout): def save_and_close(self): # 获取用户选中的文件夹路径 selected_folder = self.ids.filechooser.path # 这里可以添加路径保存、传递给主程序等逻辑 print(f"已选择保存文件夹: {selected_folder}") # 关闭当前弹窗 self.parent.dismiss() class FloatLayout2(FloatLayout): def spinner_clicked(self, value): pass class BoxLayout1(BoxLayout): pass class BoxLayout2(BoxLayout): pass class BoxLayout3(BoxLayout): pass class BoxLayout4(BoxLayout): pass class MyApp(App): def build(self): return BoxLayout1() if __name__ == "__main__": MyApp().run()
修改后的KV代码
#:import Factory kivy.factory.Factory <BoxLayout3>: Label: text: "Audio:" halign: 'center' font_size:'20sp' CheckBox: <BoxLayout4>: Label: text: "Video:" halign: 'center' font_size:'20sp' CheckBox: <FileWidget>: FileChooserIconView: id: filechooser dirselect: True Button: id:my_button text: 'Save' size_hint: (0.1, 0.1) pos_hint:{'x': 0, 'y': 0} on_release: root.save_and_close() <MyPopup>: auto_dismiss: False title: "Select a folder" FileWidget: <FloatLayout1>: Button: text: 'Folder' on_release: Factory.MyPopup().open() size_hint: None, None size: 130, 50 pos_hint: {'x':0.2,'y':.4} <FloatLayout2>: Spinner: id: spinner_id text: "Quality" values: ['144p', '240p', '360p', '480p', '720p', '1080p', '1440p', '2160p'] on_text: root.spinner_clicked(spinner_id.text) size_hint: None, None size: 130, 50 pos_hint: {'x': .2, 'y':.4} <BoxLayout2>: cols:4 BoxLayout3: BoxLayout4: FloatLayout2: FloatLayout1: <BoxLayout1>: orientation:'vertical' Label: text: "YouTube Downloader" halign: 'center' bold: True font_size:'50sp' TextInput: size_hint: (.5, .2) multiline: False hint_text: 'Enter the link of the Youtube video you want to download.' pos_hint: {"x": 0.25} BoxLayout2: Button: text: "Submit" size_hint: (.5, .2) pos_hint: {"x": 0.25}
额外优化点
- 给
FileChooserIconView添加dirselect: True,确保用户只能选择文件夹,符合需求 - 移除了
<BoxLayout1>中冗余的cols:3参数(垂直布局无需设置列数)
内容的提问来源于stack exchange,提问作者apps are the best
相关产品推荐
相关产品推荐

