PySimpleGUI搜索GUI Listbox右键Open/Save事件触发报错求助
问题排查与修复
已定位的错误点
- 语法错误:主事件循环
while True代码块缩进错误,多了前置空格,运行直接报错 - 事件逻辑错误:右键菜单的
Open/Save选项触发的事件值就是字符串Open/Save,原代码把对应逻辑写在了if event == '-RESULTS-'分支下,永远无法触发 - 路径存储错误:搜索结果只存储了文件名,没有拼接完整路径,后续打开/保存操作无法定位到真实文件
- 计数逻辑错误:仅在
CONTAINS匹配模式下会累加匹配数matches,其余两种匹配模式无计数,搜索结果统计不准 - 空函数问题:
open_file/save_file无实现逻辑,无法完成对应操作
修复后完整可运行代码
import PySimpleGUI as sg import os import threading import shutil from tkinter.filedialog import askdirectory # 全局配置 SEARCH_ROOT = r'G:\MOTOR\DataExtracts' os.chdir(SEARCH_ROOT) def search(values, window): """Perform a search based on term and type""" global results results.clear() matches = 0 # 匹配数量 records = 0 # 扫描总文件数 window['-RESULTS-'].update(values=results) window['-INFO-'].update(value='搜索中...') # 遍历搜索路径 for root, _, files in os.walk(values['-PATH-']): for file in files: records +=1 full_path = os.path.join(root, file) is_match = False # 三种匹配逻辑 if values['-ENDSWITH-'] and file.lower().endswith(values['-TERM-'].lower()): is_match = True if values['-STARTSWITH-'] and file.lower().startswith(values['-TERM-'].lower()): is_match = True if values['-CONTAINS-'] and values['-TERM-'].lower() in file.lower(): is_match = True if is_match: matches +=1 results.append(full_path) window['-RESULTS-'].update(results) window['-INFO-'].update('输入搜索关键词点击`搜索`开始') sg.PopupOK(f'搜索完成!\n共扫描文件:{records} 个\n匹配文件:{matches} 个') def open_files(file_list): """批量打开选中的文件""" success = 0 fail = 0 for file in file_list: try: os.startfile(file) # Windows系统默认程序打开 success +=1 except Exception as e: fail +=1 sg.Popup(f'打开完成!成功:{success} 个,失败:{fail} 个') def save_files(file_list): """批量保存选中的文件到指定目录""" save_dir = askdirectory(title='选择保存目录') if not save_dir: return success = 0 fail = 0 total = len(file_list) for idx, file in enumerate(file_list): try: file_name = os.path.basename(file) target_path = os.path.join(save_dir, file_name) shutil.copy2(file, target_path) success +=1 # 更新进度提示 window['-INFO-'].update(f'保存中:{idx+1}/{total}') except Exception as e: fail +=1 window['-INFO-'].update('输入搜索关键词点击`搜索`开始') sg.Popup(f'保存完成!成功:{success} 个,失败:{fail} 个') # 初始化界面 results = [] sg.change_look_and_feel('Black') command = ['Open', 'Save'] layout = [ [sg.Text('搜索关键词', size=(11, 1)), sg.Input('', size=(40, 1), key='-TERM-'), sg.Radio('包含', group_id='search_type', size=(10, 1), default=True, key='-CONTAINS-'), sg.Radio('开头匹配', group_id='search_type', size=(10, 1), key='-STARTSWITH-'), sg.Radio('后缀匹配', group_id='search_type', size=(10, 1), key='-ENDSWITH-')], [sg.Text('搜索路径', size=(11, 1)), sg.Combo(['ShdwProd/','Other/'],readonly=True, size=(38, 1), key='-PATH-'), sg.Button('搜索', size=(20, 1), key='-SEARCH-'), sg.Button('下载选中', size=(20, 1), key='-DOWNLOAD-')], [sg.Text('输入搜索关键词点击`搜索`开始', key='-INFO-')], [sg.Listbox(values=results, size=(100, 28), bind_return_key = True, enable_events=True, key='-RESULTS-', right_click_menu=['&右键菜单', command])], [sg.Help(key='-HELP-')]] window = sg.Window('文件搜索工具', layout=layout, finalize=True, return_keyboard_events=True) window['-RESULTS-'].Widget.config(selectmode = sg.LISTBOX_SELECT_MODE_EXTENDED) window['-RESULTS-'].expand(expand_x=True, expand_y=True) # 主事件循环 while True: event, values = window.read() if event is None: break if event == '-SEARCH-': # 搜索放到子线程避免GUI卡死 if not values['-TERM-'].strip(): sg.PopupWarning('请输入搜索关键词') continue threading.Thread(target=search, args=(values, window), daemon=True).start() # 右键Open逻辑 if event == 'Open': selected = values['-RESULTS-'] if selected: open_files(selected) # 右键Save和下载按钮共用保存逻辑 if event in ('Save', '-DOWNLOAD-'): selected = values['-RESULTS-'] if selected: save_files(selected) if event == '-HELP-': sg.Popup("使用说明:\n1. 输入搜索关键词,选择匹配规则和搜索路径\n2. 点击搜索开始查找文件\n3. 多选结果后右键可打开/保存,也可直接点击下载选中按钮批量保存") window.close()
功能说明
- 修复了所有语法和逻辑错误,可直接运行
- 支持多选文件后右键打开、右键保存,也可点击下载按钮批量保存
- 搜索过程放到子线程运行,不会卡住GUI界面
- 增加了操作结果提示,所有操作完成后都会弹出统计结果
- 搜索完成弹窗会显示扫描总文件数和匹配文件数
- 打开/保存都增加了异常处理,不会因为单个文件报错导致程序崩溃
内容的提问来源于stack exchange,提问作者EUNHEE CHOI
相关产品推荐
相关产品推荐

