2

I am working on a script that simplifies my daily work routines. Eventually I added a GUI to it using PySimpleGUI. As I add functionality the event loop continues to grow and I am wondering if this is the right way to go. Imagine the following code:

import PySimpleGUI as sg
layout = [
    [sg.Text("Some Text")],
    [sg.Text("Some Input", size=(1, 10))],
    [
        sg.Button("Ok", key="-buttonOk-"),
        sg.Button("Do Something", key="-buttonDoSth-"),
        sg.Button("Cancel"),
    ],
]

# Create the Window
window = sg.Window("Window Title", layout)
# Event Loop to process "events" and get the "values" of the inputs
while True:
    event, values = window.read()
    if (event == sg.WIN_CLOSED or event == "Cancel"):  
        break
    if event == "-buttonOk-":
        print("ok pressed")
    if event == "-buttonDoSth-":
        print("I am doing something")
window.close()

As I add more buttons, input fields, etc. the if event == '...': part grows, so that it is about 300 lines long by now. Is there a better way to do this? How would this be done in a "real" software package?

divingTobi
  • 2,044
  • 10
  • 25

1 Answers1

3

You can use a dictionary to map event to function called.

For example

import PySimpleGUI as sg

def do_something(*args, **kwargs):
    print("I am doing something")

def button_ok(*args, **kwargs):
    print("ok pressed")

function = {
    "-buttonOk-": button_ok,
    "-buttonDoSth-": do_something,
}

layout = [
    [sg.Text("Some Text")],
    [sg.Text("Some Input", size=(10, 1))],
    [
        sg.Button("Ok", key="-buttonOk-"),
        sg.Button("Do Something", key="-buttonDoSth-"),
        sg.Button("Cancel"),
    ],
]
window = sg.Window("Window Title", layout)

while True:
    event, values = window.read()
    if (event == sg.WIN_CLOSED or event == "Cancel"):
        break
    elif event in function:
        function[event]()

window.close()
Jason Yang
  • 11,284
  • 2
  • 9
  • 23
  • I assume this requires global variables, no? I would geenrall pass `window` and `values` to `function[event]()`, so the function can work on it, but for everything else that needs to be available from different parts of the program, I would need at least one global variable. – divingTobi Jun 02 '22 at 09:35
  • 1
    You can define a class with methods to handle events, then save values from different parts of the program to attributes of this class. – Jason Yang Jun 02 '22 at 09:41
  • 1
    The topic is basically one of "dispatchers". There is a demo program (Demo_Dispatchers.py) that shows several ways this can be approached. In OO based GUIs, the event handling is spread out across many objects. The advantage of the PSG event loop is the centralization of event handling. You can go to one location and quickly find what happens when an event is generated. You do have multiple ways to structure this code. – Mike from PSG Jun 03 '22 at 12:50