PySimpleGUI多窗口应用:窗口3、4点击Calculate后事件循环崩溃
多窗口PySimpleGUI程序修复:Function3窗口Calculate按钮触发崩溃问题
问题描述
我正在开发一个包含4个窗口的简易GUI程序,首页窗口可跳转到3个功能窗口,完成操作后能返回首页。目前首页和Function2窗口导航及功能正常,但点击Function3窗口的Calculate按钮后,事件循环崩溃,尽管该窗口逻辑与Function2完全一致。原代码如下:
import PySimpleGUI as sg def make_function1_window(): layout = [ [sg.Text("Calculate Function 1")], [sg.Text("0.0000", justification="right", background_color="#2a2a2a", text_color="white", relief="sunken", key="_DISPLAY_")], [sg.Input("Enter input...", justification="left", key="_F1_INPUT_")], [sg.Button("Calculate"), sg.Button("Home")] ] return sg.Window("Function1", layout) def make_function2_window(): layout = [ [sg.Text("Calculate Function 2")], [sg.Text("0.0000", justification="right", background_color="#2a2a2a", text_color="white", relief="sunken", key="_DISPLAY_")], [sg.Input("Enter input...", justification="left", key="_F1_INPUT_")], [sg.Button("Calculate"), sg.Button("Home")] ] return sg.Window("Function2", layout) def make_function3_window(): layout = [ [sg.Text("Calculate Function 2")], [sg.Text("0.0000", justification="right", background_color="#2a2a2a", text_color="white", relief="sunken", key="_DISPLAY_")], [sg.Input("Enter input...", justification="left", key="_F1_INPUT_")], [sg.Button("Calculate"), sg.Button("Home")] ] return sg.Window("Function3", layout) layout_home = [ [sg.Text("Welcome to the program", font=("Arial", 12, "bold"))], [sg.Button("Function 1"), sg.Button("Function 2"), sg.Button("Function 3")], [sg.Button("Exit")] ] home_window = sg.Window("Program Home", layout_home) function1_active = function2_active = function3_active = False while True: if not function1_active: event, values = home_window.read() if event is None or event == "Exit": break if not function1_active and event == "Function 1": function1_active = True home_window.hide() function1_window = make_function1_window() if not function1_active and event == "Function 2": function2_active = True home_window.hide() function2_window = make_function2_window() if not function1_active and event == "Function 3": function3_active = True home_window.hide() function3_window = make_function3_window() if function1_active: event, values = function1_window.read() if event == None: break elif event == "Home": function1_active = False function1_window.close() home_window.un_hide() elif event == "Calculate": function1_window["_DISPLAY_"].update(value="Doing stuff") function1_window.refresh() if function2_active: event, values = function2_window.read() if event == None: break elif event == "Home": function2_active = False function2_window.close() home_window.un_hide() elif event == "Calculate": function2_window["_DISPLAY_"].update(value="Doing stuff") function2_window.refresh() if function3_active: event, values = function3_window.read() if event == None: break elif event == "Home": function3_active = False function3_window.close() home_window.un_hide() elif event == "Calculate": function3_window["_DISPLAY_"].update(value="Doing stuff") function3_window.refresh() home_window.close()
问题原因
原事件循环逻辑存在致命缺陷:并行判断所有窗口的激活状态,导致多个窗口的read()方法被同时调用,引发事件处理冲突、阻塞,最终导致循环崩溃。
解决方案
改用PySimpleGUI提供的sg.read_all_windows()统一处理多窗口事件,同时重构代码结构,消除重复逻辑,简化状态管理。修复后的代码如下:
import PySimpleGUI as sg def make_function_window(window_num): # 统一创建功能窗口的函数,消除重复代码 layout = [ [sg.Text(f"Calculate Function {window_num}")], [sg.Text("0.0000", justification="right", background_color="#2a2a2a", text_color="white", relief="sunken", key="_DISPLAY_")], [sg.Input(f"Enter input for Function {window_num}...", justification="left", key=f"_F{window_num}_INPUT_")], [sg.Button("Calculate"), sg.Button("Home")] ] return sg.Window(f"Function{window_num}", layout) layout_home = [ [sg.Text("Welcome to the program", font=("Arial", 12, "bold"))], [sg.Button("Function 1"), sg.Button("Function 2"), sg.Button("Function 3")], [sg.Button("Exit")] ] home_window = sg.Window("Program Home", layout_home) # 用字典管理已打开的功能窗口,简化状态跟踪 function_windows = {} while True: # 统一读取所有窗口的事件,避免多read()冲突 window, event, values = sg.read_all_windows() # 处理全局关闭事件 if event is None or event == "Exit": # 关闭所有功能窗口 for win in function_windows.values(): win.close() home_window.close() break # 首页窗口事件处理 if window == home_window: if event.startswith("Function"): # 提取功能窗口编号 num = event.split()[-1] home_window.hide() # 创建并存储功能窗口 function_window = make_function_window(num) function_windows[num] = function_window # 功能窗口事件处理 else: # 获取当前功能窗口编号 window_num = window.Title.split()[-1] if event == "Home": # 关闭功能窗口并返回首页 window.close() del function_windows[window_num] home_window.un_hide() elif event == "Calculate": # 更新显示内容,无需手动调用refresh() window["_DISPLAY_"].update(value="Doing stuff")
关键改动说明
- 用
make_function_window统一创建功能窗口,修复原Function3窗口文本错误,消除重复代码。 - 使用
sg.read_all_windows()统一处理所有窗口事件,彻底解决多read()调用导致的冲突问题。 - 用字典
function_windows管理已打开的功能窗口,简化状态跟踪逻辑。 - 移除不必要的
refresh()调用,PySimpleGUI的update()方法会自动触发界面刷新。
内容的提问来源于stack exchange,提问作者Callum
相关产品推荐
相关产品推荐

