Python Forum
PySimpleGUI Bugging out
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
PySimpleGUI Bugging out
#4
I played around with your code. It is an, um, er, interesting approach. I would never have come up with the idea of destroying and re-creating windows just to update the widgets. The top row of buttons is also an unusual way to present different views.

Here are some ideas you may find interesting. I modified the code to remove recursion.

Recursion is when a function calls itself, either directly or indirectly through other functions. Your code has a lot of recursion. Functions call themselves to update the window or call functions to draw other windows that may in turn call the original function. This is a bad thing because it eats up memory. It is so bad that Python places an upper limit on how many levels of function calls are allowed. If you program reaches that limit, an exception is thrown.

To remove the recursion I rewrote the code to return control to a window switcher which calls the function to draw the next window. Instead of login() calling main(), login() now sets a variable and returns. The window switcher.
switch_window(login)  # Start with login window
while next_window:
    next_window() # execute function to draw next window
To switch from the current window to a new window, the window event loop assigns "next_window" to be the function that draws the next window, then the current window exits its event loop and lets control return to the window switcher loop. It uses a couple of convenience functions to help with this.
def switch_window(window_func):
    '''Close current window and set function to open new window'''
    global next_window, window_open
    next_window = window_func
    window_open = False

def show_window(title, layout):
    '''Create new window using layout.  Position window in same location as current window'''
    global window, window_open
    if window:
        window.close()
    window = sg.Window(title, layout, size=(600, 500), enable_close_attempted_event=True, location=sg.user_settings_get_entry('-WINDOW_LOCATION-', (None, None)))
    window_open = True
switch_window() sets the next_window function variable and sets window_open to False, causing the event loop to exit. show_window() draws the new window.

I changed the way window location was saved and restored. I have the window send an event if you click on the close window decoration. In the event handler I capture that event, save the window location, and close the window. I save the window location in a PySimpleGUI user setting named '-WINDOW_LOCATION-', and when the new window is drawn it uses the user setting to set the location of the new window.

I rewrote the login window to allow multiple login attempts without having to redraw the window. If the user enters in invalid username or password it clears the inputs, displays a message in a popup, and sets focus back to the user input.

Clearing the inputs is easy. You can set a flag to automatically clear an input when it is read, and I did that in the layout
    layout = [
        [sg.T("Username")],
        [sg.InputText(key = "-USER-", do_not_clear=False)],
        [sg.T("Password")],
        [sg.InputText(key = "-PASSWORD-", do_not_clear=False)],
        [sg.Button("OK", bind_return_key=True, key="-OK-")],
    ]
Setting the focus back to the user input was a bit trickier. I had to call the set_focus() method for the user input.
                window['-USER-'].set_focus()  Give keyboard focus to the user input widget
The entire program:
import PySimpleGUI as sg

accounts = {"Admin":"Administrator", "User":"OneTwoThree"}  # use database or dictionary for passwords. Easier to use than lists of lists.
window = None  # Variables used by the window switcher
window_open = False
next_window = None

def switch_window(window_func):
    '''Close current window and set function to open new window'''
    global next_window, window_open
    next_window = window_func
    window_open = False

def show_window(title, layout):
    '''Create new window using layout.  Position window in same location as current window'''
    global window, window_open
    if window:
        window.close()
    window = sg.Window(title, layout, size=(600, 500), enable_close_attempted_event=True, location=sg.user_settings_get_entry('-WINDOW_LOCATION-', (None, None)))
    window_open = True

def main_window_menu(event, values):
    '''Process events common to all windows'''
    if event == sg.WINDOW_CLOSE_ATTEMPTED_EVENT:
        sg.user_settings_set_entry('-WINDOW_LOCATION-', window.current_location())  # Save window location before closing
        window.close()
    if event == sg.WIN_CLOSED:
        switch_window(login)
    if event == "User List":
        switch_window(user_list)
    if event == "View Logged Equipment":            
        switch_window(user_equip)

def login():
    '''User login window'''
    layout = [
        [sg.T("Username")],
        [sg.InputText(key = "-USER-", do_not_clear=False)],
        [sg.T("Password")],
        [sg.InputText(key = "-PASSWORD-", do_not_clear=False)],
        [sg.Button("OK", bind_return_key=True, key="-OK-")],
    ]
    show_window("Login", layout)
    while window and window_open:
        event, values = window.read()  # window.read() belongs inside while loop
        if event == sg.WINDOW_CLOSE_ATTEMPTED_EVENT:
            window.close()
        if event == sg.WIN_CLOSED:
            switch_window(None)
        if event == "-OK-":
            if accounts.get(values['-USER-']) == values['-PASSWORD-']:
                switch_window(user_list)
            else:
                sg.popup('Invalid Login.','Please try again.')
                window['-USER-'].set_focus()

def user_list():
    '''Some window that does something'''
    layout = [
        [sg.B("View Logged Equipment"), sg.B("User List")],
        [sg.B("User List Push Me", bind_return_key=True, key='-PUSH_ME-')]
    ]
    show_window("User List", layout)
    while window and window_open:
        event, values = window.read()
        if event == "-PUSH_ME-":  # Do event handling specific to this window first
            print('In user list window')
        else:
            main_window_menu(event, values)  # Handle events common to many windows (the top buttons)
 
def user_equip():
    '''Some window that does different things'''
    layout = [
        [sg.B("View Logged Equipment"), sg.B("User List")],
        [sg.B("User Equipment Push Me", bind_return_key=True, key='-PUSH_ME-')]
    ]
    show_window("User Equipment", layout)
    while window and window_open:
        event, values = window.read()
        if event == "-PUSH_ME-":  
            print('In user equipment window')
        else:
            main_window_menu(event, values)
  
switch_window(login)  # Start with login window
while next_window:
    next_window() # execute function to draw next window
I do not think this is the right way to write this program. I would make a tabbed window and create tabs for Logged Equipment, User List, Log Equipment Out, Open Tickets and Open Requests. Instead of destroying and re-creating the windows, the event loop would update the existing widgets to display new information. The resulting program would maybe be 200 lines long to do everything your program currently does.
Reply


Messages In This Thread
PySimpleGUI Bugging out - by jamesaarr - Sep-22-2021, 03:02 PM
RE: PySimpleGUI Bugging out - by deanhystad - Sep-22-2021, 05:26 PM
RE: PySimpleGUI Bugging out - by jamesaarr - Sep-23-2021, 09:01 AM
RE: PySimpleGUI Bugging out - by deanhystad - Sep-23-2021, 12:57 PM
RE: PySimpleGUI Bugging out - by jamesaarr - Sep-23-2021, 01:47 PM
RE: PySimpleGUI Bugging out - by deanhystad - Sep-23-2021, 01:51 PM
RE: PySimpleGUI Bugging out - by jamesaarr - Sep-29-2021, 10:47 AM
RE: PySimpleGUI Bugging out - by deanhystad - Sep-29-2021, 06:47 PM
RE: PySimpleGUI Bugging out - by deanhystad - Sep-30-2021, 07:57 PM
RE: PySimpleGUI Bugging out - by deanhystad - Oct-05-2021, 07:26 PM

Possibly Related Threads…
Thread Author Replies Views Last Post
  PySimpleGUI Try Except jamesaarr 1 1,989 Nov-18-2021, 02:02 PM
Last Post: jamesaarr

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020