Kivy FileChooserListView如何禁用文件夹展开或过滤展开内容
Kivy FileChooserListView 展开箭头过滤失效问题修复
问题核心原因:点击文件夹主体触发的open_entry是目录跳转逻辑(将目标目录设为组件当前根路径),但点击左侧小箭头触发的是TreeView自带的就地展开逻辑,不会调用重写的open_entry方法,自然不会执行路径跳转和过滤规则。
方案1:直接禁用左侧展开箭头功能
从根源避免用户触发非预期行为,通过隐藏+禁用目录项的展开按钮实现:
import os from kivy.uix.filechooser import FileChooserListView class CustomFileChooser(FileChooserListView): def __init__(self, **kwargs): super().__init__(**kwargs) self.bind(on_entry_added=self._process_dir_entry) def _process_dir_entry(self, _, entry, *args): # 仅处理目录类型的条目 if not entry.is_dir: return # 隐藏展开箭头、禁用点击 toggle_btn = entry.ids.toggle_button toggle_btn.opacity = 0 toggle_btn.disabled = True toggle_btn.unbind(on_release=entry.toggle_expanded) # 保留原有跳转、过滤逻辑 def open_entry(self, entry): maps_path = os.path.join(entry.path, "maps") self.filters = [] if os.path.exists(maps_path): self.filters = ["*.yaml"] entry.path = maps_path return super().open_entry(entry) site_root = os.path.join( os.path.expanduser("~"), "catkin_ws", "src", "my_sites", "sites" ) if entry.path != site_root: entry.path = site_root return super().open_entry(entry)
实现后用户看不到也点不了左侧展开箭头,只能通过点击文件夹主体触发预设逻辑,不会出现过滤失效。
方案2:保留展开功能,全层级应用过滤与跳转规则
如果需要保留层级展开浏览能力,不能只在open_entry中写逻辑,需要把跳转、过滤规则下沉到文件系统遍历层,确保任何场景下加载目录内容都会执行规则:
import os from kivy.uix.filechooser import FileChooserListView, FileSystemLocal class CustomFileSystem(FileSystemLocal): # 重写目录读取逻辑,自动跳转到maps子目录 def listdir(self, path): maps_path = os.path.join(path, "maps") if os.path.isdir(maps_path): return super().listdir(maps_path) return super().listdir(path) class CustomFileChooser(FileChooserListView): def __init__(self, **kwargs): self.file_system = CustomFileSystem() super().__init__(**kwargs) # 全局固定yaml过滤规则,无需在open_entry中反复设置 self.filters = ["*.yaml"] # 固定根目录为指定sites路径 self.bind(path=self._enforce_root_path) def _enforce_root_path(self, *args): target_root = os.path.join( os.path.expanduser("~"), "catkin_ws", "src", "my_sites", "sites" ) if self.path != target_root and os.path.exists(target_root): self.unbind(path=self._enforce_root_path) self.path = target_root self.bind(path=self._enforce_root_path) def open_entry(self, entry): return super().open_entry(entry)
该实现下,无论是点击进入目录还是点箭头展开子目录,所有加载的内容都会自动执行maps子目录跳转,且仅显示yaml格式文件,不会出现漏过滤的情况。
注意事项
不要在open_entry中反复重置filters为空列表再重新赋值,全局固定过滤规则稳定性更高,也能避免切换过程中短暂显示非目标文件的闪烁问题。
内容的提问来源于stack exchange,提问作者Syrine
相关产品推荐
相关产品推荐

