You need to enable JavaScript to run this app. PySimpleGUI搜索GUI Listbox右键Open/Save事件触发报错求助
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 01:36:03