Kivy FileChooser访问系统文件报错pywintypes.error(32)求助
解决Kivy FileChooser访问被占用系统文件抛出pywintypes.error(32)的问题
核心问题原因
Kivy的FileChooser组件默认会尝试读取目录下所有文件的属性,包括系统锁定的文件(如hiberfil.sys、DumpStack.log.tmp)。这类文件被其他进程占用时,访问会触发Windows 32号错误(进程无法访问文件,因为另一个进程正在使用它)。而自定义过滤函数是在文件扫描完成后才生效,无法阻止扫描过程中的错误抛出。
解决方案
1. 重写FileChooser的文件扫描逻辑(推荐)
继承Kivy的FileChooserListView或FileChooserIconView,重写文件获取方法,在遍历文件时捕获特定错误并跳过被占用的文件:
from kivy.uix.filechooser import FileChooserListView import pywintypes # 定义已知需要跳过的系统文件 SYSTEM_EXCLUDE_FILES = {'hiberfil.sys', 'DumpStack.log.tmp', 'pagefile.sys', 'swapfile.sys'} class SafeFileChooser(FileChooserListView): def _get_files(self, path, *args): try: # 调用父类方法获取原始文件列表 raw_files = super()._get_files(path, *args) filtered_files = [] for file_obj in raw_files: # 先跳过已知系统文件 if file_obj.name in SYSTEM_EXCLUDE_FILES: continue # 尝试获取文件状态,捕获被占用错误 try: file_obj.stat() filtered_files.append(file_obj) except pywintypes.error as e: # 仅忽略32号文件被占用错误 if e.winerror != 32: raise return filtered_files # 处理目录本身被占用的情况 except pywintypes.error as e: if e.winerror == 32: return [] raise
使用时直接替换原有的FileChooser组件:
from kivy.app import App class TestApp(App): def build(self): return SafeFileChooser() if __name__ == '__main__': TestApp().run()
2. 全局异常捕获(临时方案)
如果不想修改FileChooser代码,可以添加全局异常钩子,忽略32号文件占用错误。但此方法会掩盖所有同类错误,谨慎使用:
import sys import pywintypes def win32_error_filter(exctype, value, traceback): if exctype == pywintypes.error and value.winerror == 32: # 忽略文件被占用的错误 return # 其他错误交给默认处理逻辑 sys.__excepthook__(exctype, value, traceback) sys.excepthook = win32_error_filter
3. 调整Kivy文件扫描配置
尝试禁用FileChooser的系统原生扫描功能(部分版本有效),在初始化组件时设置use_native_dialog=False,强制使用Kivy自身的扫描逻辑:
FileChooserListView(use_native_dialog=False)
注意:此方法可能影响组件性能或显示效果,需测试验证。
内容的提问来源于stack exchange,提问作者Brian Kay Walker
相关产品推荐
相关产品推荐

