Search code examples
pysimplegui

Multi-window application crashing event loop in window 3 and 4 even though the same operation works in window 2


I'm attempting to make a simple 4 window GUI. The first window a home window and the subsequent 3, seperate functions. I want to navigate to windows 2, 3 and 4 from the home window and be able to "do stuff" and return to home. Here's a minimum workable version of my code:

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()

The GUI navigates correctly for the home window and window 2. However, if you click the "calculate" event on windows 3 and 4 the event loop seems to crash, even though the functionality of windows 3 and 4 is exactly the same as window 2.

I'd be grateful for any help on this issue.

Cheers, Callum

I have tried adding the .refresh() command. I want to be able to use the "calculate" event on each window and then use another event.


Solution

  • The logic for win1 is different with the logic for win2 and win3, it will be back to main window read if you are in the win2 or win3 after Calculate button clicked, but the sub-window is shown and main window is hided.

    IMO, you get the code complex and difficult to maintain.

    Example Code

    import PySimpleGUI as sg
    
    def function_window(index):
        layout = [
            [sg.Text(f"Calculate Function {index}")],
            [sg.Text("0.0000", justification="right", background_color="#2a2a2a", text_color="white", relief="sunken", key="_DISPLAY_")],
            [sg.Input("Enter input...", justification="left", key="_INPUT_")],
            [sg.Button("Calculate"), sg.Button("Home")]
        ]
        window = sg.Window(f"Function{index}", layout)
        while True:
            event, values = window.read()
            if event in (sg.WIN_CLOSED, "Home"):
                break
            elif event == "Calculate":
                window["_DISPLAY_"].update(value="Doing stuff")
        window.close()
    
    layout = [
        [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")]
    ]
    window = sg.Window("Program Home", layout)
    
    while True:
    
        event, values = window.read()
    
        if event in (sg.WIN_CLOSED, "Exit"):
            break
        elif event.startswith("Function"):
            index = event.split(" ")[1]
            window.hide()
            function_window(index)
            window.un_hide()
    
    window.close()