解决PySimpleGUI脚本中InputText的'-url-' KeyError问题
解决PySimpleGUI中KeyError: '-url-'的问题
错误信息
Traceback (most recent call last): File ....\play_download.py", line 55, in url = values['-url-'] ~~~~~~^^^^^^^^^ KeyError: '-url-'
该错误在点击单选按钮download_video_with_yt_dlp时触发。
相关代码
import PySimpleGUI as sg from my_scripts import * from my_constants import * import sys import glob import yt_dlp sg.theme_background_color('#3d5c5c') sg.set_options(font=('Fira Code', 16)) l1 = sg.Text('Put url here',font=('Fira Code', 16), expand_x=True, justification='center') l2 = sg.Text('Put 1 for Chef_Max_Mariola, 2 for JuliaCrossBow, 3 for French_Vibes, 4 for Studio_Italiano_InClasse, 5 for D:', font=('Fira Code', 16), expand_x=True, justification='center') t1 = sg.Text('', enable_events=True, font=('Fira Code', 16), expand_x=True, justification='left') t2 = sg.Text('', enable_events=True, font=('Fira Code', 16), expand_x=False, justification='left') def delete_video_in_D(): list_of_files = [os.remove(p) for p in glob.glob(r'D:\\*.*') if (os.path.isfile(p) and is_video(p))] layout1 = [ [sg.Radio(key, 'Radio', enable_events=True, key=key) for key in ['Chef_Max_Mariola', 'JuliaCrossBow', 'French_Vibes', 'Studio_Italiano_InClasse', 'download_video_with_yt_dlp']]] layout2 = [ [sg.Radio(key, 'Radio', enable_events=True, key=key) for key in ['Chef_Max_Mariola', 'JuliaCrossBow', 'French_Vibes', 'Studio_Italiano_InClasse', 'download_video_with_yt_dlp']], [l1],[t1, sg.InputText(key='-url-')], [l2], [t2, sg.InputText(key='-folder-')]] FOLDERS = {'1:Chef_Max_Mariola_PATH', '2:JuliaCrossBow_PATH', '3:French_Vibes_PATH', '4:Studio_Italiano_InClasse_PATH', '5:r"D:\\"'} window = sg.Window('Main Window', layout1) while True: event, values = window.read() if event == sg.WIN_CLOSED: break elif event == 'Chef_Max_Mariola': play_videos_from_folder(Chef_Max_Mariola_PATH) elif event == 'JuliaCrossBow': play_videos_from_folder(JuliaCrossBow_PATH) elif event == 'French_Vibes': play_videos_from_folder(French_Vibes_PATH) elif event == 'Studio_Italiano_InClasse': play_videos_from_folder(Studio_Italiano_InClasse_PATH) elif event == 'download_video_with_yt_dlp': delete_video_in_D() window = sg.Window('Main Window', layout2) url = values['-url-'] folder = values['-folder-'] os.chdir(FOLDERS[folder]) try: with yt_dlp.YoutubeDL() as ydl: ydl.download(link) list_of_files = glob.glob('*.*') latest_file = max(list_of_files, key=os.path.getctime) # print("Download is completed successfully") # print(latest_file) new_name = re.sub(r'\s*\[.*?\]\s*', '', latest_file ) os.rename(latest_file, new_name) proc = subprocess.Popen([r'C:\\Program Files\\VideoLAN\\VLC\\vlc.exe', new_name], close_fds=True) time.sleep(2) except Exception as e: print('Error on line {}'.format(sys.exc_info()[-1].tb_lineno), type(e).__name__, e) window.close()
错误原因
点击download_video_with_yt_dlp单选按钮后,程序创建了包含InputText(key='-url-')的新窗口,但直接使用旧窗口的values字典——这个旧字典是从初始窗口(layout1)读取的,根本没有'-url-'键,因此抛出KeyError。
修复方案
- 创建新窗口后,必须调用
window.read()获取新窗口的用户输入,不能直接复用旧窗口的values。 - 原代码中
FOLDERS是集合类型,无法通过键值访问,需要改为字典。 - 修正变量名错误:原代码中使用未定义的
link变量,应该改为url。 - 创建新窗口前关闭旧窗口,避免多个窗口共存。
修改后的download_video_with_yt_dlp分支代码如下:
elif event == 'download_video_with_yt_dlp': delete_video_in_D() # 关闭旧窗口 window.close() # 创建带输入框的新窗口 window = sg.Window('Main Window', layout2) # 读取新窗口的事件和输入值 new_event, new_values = window.read() # 处理用户关闭新窗口的情况 if new_event == sg.WIN_CLOSED: break # 从新窗口的values中获取输入内容 url = new_values['-url-'] folder = new_values['-folder-'] # 将FOLDERS改为字典,确保能通过输入的数字取值 FOLDERS = { '1': Chef_Max_Mariola_PATH, '2': JuliaCrossBow_PATH, '3': French_Vibes_PATH, '4': Studio_Italiano_InClasse_PATH, '5': r"D:\\" } os.chdir(FOLDERS[folder]) try: with yt_dlp.YoutubeDL() as ydl: # 使用url变量而非未定义的link ydl.download([url]) list_of_files = glob.glob('*.*') latest_file = max(list_of_files, key=os.path.getctime) new_name = re.sub(r'\s*\[.*?\]\s*', '', latest_file ) os.rename(latest_file, new_name) proc = subprocess.Popen([r'C:\\Program Files\\VideoLAN\\VLC\\vlc.exe', new_name], close_fds=True) time.sleep(2) except Exception as e: print('Error on line {}'.format(sys.exc_info()[-1].tb_lineno), type(e).__name__, e)
内容的提问来源于stack exchange,提问作者LetzerWille
相关产品推荐
相关产品推荐

