PySimpleGUI技术需求:如何实现加载时仅显示已填充行
问题描述
我基于PySimpleGUI开发了一个简易GUI,示例中包含三行输入区域,该逻辑可扩展至更多行。需求为:填充部分或全部行内容后保存,加载保存的文件时,仅显示已填充内容的行,而非所有行。我尝试了如下代码,但未实现预期效果:
import PySimpleGUI as sg from datetime import datetime import base64 from pathlib import Path import webbrowser sg.theme('DarkTeal9') layout_1 = [[sg.InputText("", key="-IT2-", font='Arial 9', size=(10,1)), sg.Combo(["Item1", "Item2", "Item3"],size=(20,1), key='-TEST2-', font='Arial 9'), sg.CalendarButton("", close_when_date_chosen=True, target='-IN2-', font='Arial 9', no_titlebar=False, format='%d-%b-%Y'), sg.InputText("", key='-IN2-', size=(20,1), font='Arial 9')]] layout_a = [[sg.Button("row 2")]] layout_2 = [[sg.InputText("", key="-IT3-", font='Arial 9', size=(10,1)), sg.Combo(["Item1", "Item2", "Item3"],size=(20,1), key='-TEST3-', font='Arial 9'), sg.CalendarButton("", close_when_date_chosen=True, target='-IN3-', font='Arial 9', no_titlebar=False, format='%d-%b-%Y'), sg.InputText("", key='-IN3-', size=(20,1), font='Arial 9')]] layout_b =[[sg.Button("row 3")]] layout_3 = [[sg.InputText("", key="-IT4-", font='Arial 9', size=(10,1), visible=True), sg.Combo(["Item1", "Item2", "Item3"],size=(20,1), key='-TEST4-', font='Arial 9'), sg.CalendarButton("", close_when_date_chosen=True, target='-IN4-', font='Arial 9', no_titlebar=False, format='%d-%b-%Y'), sg.InputText("", key='-IN4-', size=(20,1), font='Arial 9', justification="c")]] layout = [ [sg.Column(layout_1, key='-LAY1-'), sg.Column(layout_a, visible=True, key="-LAYA-")], [sg.Column(layout_2, visible=False, key='-LAY2-'), sg.Column(layout_b, visible=False, key="-LAYB-")], [sg.Column(layout_3, visible=False, key='-LAY3-')], [sg.Button ("Save"), sg.Button ("Load"), sg.Button('Exit'),], ] window = sg.Window("", layout) while True: event, values = window.read() if event == 'Save': file_name = sg.popup_get_file("Save", save_as=True, no_window=True) window.SaveToDisk(file_name) if event == 'Load': file_name = sg.popup_get_file('Load', no_window=True) window.LoadFromDisk(file_name) if values["-IT2-"] != "": window[f'-LAY1-'].update(visible=True) window[f'-LAYA-'].update(visible=False) if values ["-IT3-"] != "": window[f'-LAY2-'].update(visible=True) if values["-IT4-"] != "": window[f'-LAY3-'].update(visible=True) if event == sg.WIN_CLOSED or event == 'Exit': break window.close() if event == 'row 2': window[f'-LAY2-'].update(visible=True) window[f'-LAYA-'].update(visible=False) window[f'-LAYB-'].update(visible=True) layout = str(event) if event == 'row 3': window[f'-LAY3-'].update(visible=True) window[f'-LAYB-'].update(visible=False) layout = str(event) window.close()
解决方案
你的代码存在几个关键问题:
- 加载文件时未先重置所有行的可见状态,导致之前显示的行不会自动隐藏
window.LoadFromDisk后直接使用values可能无法获取最新加载的数据- 判断逻辑仅检查输入框,未考虑下拉框、日期输入等其他控件是否有内容
window.close()位置错误,break后不会执行该行代码
下面是修改后的完整代码,实现了加载时仅显示有内容的行:
import PySimpleGUI as sg from datetime import datetime import base64 from pathlib import Path import webbrowser sg.theme('DarkTeal9') # 定义行模板,方便后续扩展更多行 def create_row(row_num): return [ sg.InputText("", key=f"-IT{row_num+1}-", font='Arial 9', size=(10,1)), sg.Combo(["Item1", "Item2", "Item3"], size=(20,1), key=f'-TEST{row_num+1}-', font='Arial 9'), sg.CalendarButton("", close_when_date_chosen=True, target=f'-IN{row_num+1}-', font='Arial 9', no_titlebar=False, format='%d-%b-%Y'), sg.InputText("", key=f'-IN{row_num+1}-', size=(20,1), font='Arial 9') ] # 初始化布局 layout_rows = [] # 第一行(默认显示) layout_rows.append([sg.Column([create_row(1)], key='-LAY1-'), sg.Column([[sg.Button("row 2")]], visible=True, key="-LAYA-")]) # 第二行(默认隐藏) layout_rows.append([sg.Column([create_row(2)], visible=False, key='-LAY2-'), sg.Column([[sg.Button("row 3")]], visible=False, key="-LAYB-")]) # 第三行(默认隐藏) layout_rows.append([sg.Column([create_row(3)], visible=False, key='-LAY3-')]) # 按钮行 layout_rows.append([sg.Button("Save"), sg.Button("Load"), sg.Button('Exit')]) window = sg.Window("", layout_rows) while True: event, values = window.read() if event == 'Save': file_name = sg.popup_get_file("Save", save_as=True, no_window=True) if file_name: # 避免用户取消保存 window.SaveToDisk(file_name) if event == 'Load': file_name = sg.popup_get_file('Load', no_window=True) if file_name: # 避免用户取消加载 # 先重置所有行的可见状态 window['-LAY1-'].update(visible=False) window['-LAYA-'].update(visible=True) window['-LAY2-'].update(visible=False) window['-LAYB-'].update(visible=False) window['-LAY3-'].update(visible=False) # 加载数据 window.LoadFromDisk(file_name) # 重新获取最新的values values = window.read(timeout=0)[1] # 根据内容显示对应行 # 第一行:检查任意控件是否有内容 if values["-IT2-"] or values["-TEST2-"] or values["-IN2-"]: window['-LAY1-'].update(visible=True) window['-LAYA-'].update(visible=False) # 第二行 if values["-IT3-"] or values["-TEST3-"] or values["-IN3-"]: window['-LAY2-'].update(visible=True) window['-LAYB-'].update(visible=True) # 第三行 if values["-IT4-"] or values["-TEST4-"] or values["-IN4-"]: window['-LAY3-'].update(visible=True) window['-LAYB-'].update(visible=False) if event == sg.WIN_CLOSED or event == 'Exit': break if event == 'row 2': window['-LAY2-'].update(visible=True) window['-LAYA-'].update(visible=False) window['-LAYB-'].update(visible=True) if event == 'row 3': window['-LAY3-'].update(visible=True) window['-LAYB-'].update(visible=False) window.close()
关键改动说明
- 新增
create_row函数统一行模板,方便后续扩展更多行 - 加载时先重置所有行的可见状态,避免残留之前的显示状态
- 加载后通过
window.read(timeout=0)获取最新的values数据 - 判断行是否显示时,检查该行所有控件(输入框、下拉框、日期输入)是否有内容,逻辑更严谨
- 增加文件选择的判空处理,避免用户取消操作时出错
- 修复
window.close()的位置错误
内容的提问来源于stack exchange,提问作者giovanni trivieri
相关产品推荐
相关产品推荐

