Any idea on how the event loop works in Pysimplegui? Can't figure out disabling buttons based on other inputs

Question:

So I am having many issues with Pysimplegui’s event loops, I’m trying to disable a button based on the lack of input in another part of the code (in this case it’s the lack of selection of at least one checkbox if the radio button above is pressed [but I should apply the same logic if a folder is not selected]).
I tried looking everywhere and either I can’t find a solution or people apparently manage to get through based on the cookbook (which I tried and can’t).

The code i tried is the following:

This is the part regarding the Radio buttons:

layout_1 = [
# things before...
    [sg.Radio('CSV/JSON:', "OUTPUT", default=False, key='-OutputFile-', enable_events=True)],
    [sg.Checkbox('Output as CSV', key='-OutputCSV-', disabled=True)],
    [sg.Checkbox('Output as JSON', key='-OutputJSON-', disabled=True)],
    [sg.Text('Select a folder: ')], [sg.FolderBrowse(key='-Folder-')],
    [sg.Push(), sg.Column([[sg.Button("Submit", disabled=False, key='-Submit-'), sg.Cancel()]], element_justification='c'), sg.Push()]
]

window_2 = sg.Window('Info', layout_1, finalize = True)

Then I have this while loop, which in theory, should basically disable the ability to select the output if ‘-OutputFile-‘ is False and, in case none of the two available outputs available (CSV or JSON) are selected, disable the Submit button as well. Thing is the disabling of the choices works but the Submit button is never disabled and can’t be clicked.

while True:
    event_2, values_table = window_2.read()
    if event_2 in (sg.WIN_CLOSE, 'Cancel', 'Submit', None):
        break
    elif event_2 == '-OutputFile-':
        window_2['-OutputJSON-'].update(disabled = False)
        window_2['-OutputCSV-'].update(disabled = False)
        if window_2['-OutputFile-'] and not window_2['-OutputCSV-'] and not window_2['-OutputJSON-']:
            window_2['-Submit-'].update(disabled=True)
            sg.popup('Select an output', keep_on_top=True)
    elif event_2 == '-OutputNone-':
        window_2['-OutputJSON-'].update(disabled=True)
        window_2['-OutputCSV-'].update(disabled=True)
window_2.close()

I should note that the code works without the part in the loop about the Submit button, but I need that part as well.

Another thing I tried is using is False instead of not in the part not working.

This is what the window looks like:
This is what the window looks like

PS: there might be grammatical errors in the code, unfortunately I had to copy it by and, even if I checked, there might be some error.

Asked By: kosky

||

Answers:

Not check the code in detail, but following statement is wrong. Should check them by values[...], not window_2[...] which is the element.

if window_2['-OutputFile-'] and not window_2['-OutputCSV-'] and not window_2['-OutputJSON-']

Example Code:

import PySimpleGUI as sg

sg.theme('DarkBlue4')

layout = [
    [sg.Radio('None',     'Group', default=True,  key='R1', enable_events=True)],
    [sg.Radio('CSV/JSON', 'Group',                key='R2', enable_events=True),
     sg.Checkbox('CSV',            default=False, key='C1', enable_events=True, disabled=True),
     sg.Checkbox('JSON',           default=False, key='C2', enable_events=True, disabled=True)],
    [sg.Push(), sg.Button('Submit',               key='B1',                     disabled=True)]
]

window = sg.Window("Title", layout, finalize=True)
r1, r2, c1, c2, b1 = [window[key] for key in ('R1', 'R2', 'C1', 'C2', 'B1')]

while True:

    event, values = window.read()

    if event == sg.WIN_CLOSED:
        break

    elif event in ('R1', 'R2'):
        disabled = False if values['R2'] else True
        c1.update(disabled=disabled)
        c2.update(disabled=disabled)
        state = False if not disabled and values['C1'] and values['C2'] else True
        b1.update(disabled=state)

    elif event in ('C1', 'C2'):
        state = False if values['C1'] and values['C2'] else True
        b1.update(disabled=state)

window.close()

enter image description here

Answered By: Jason Yang

You need .Get() in window_2['-OutputCSV-'].Get() and window_2['-OutputJSON-'].Get() to check if elements are selected.

if not window_2['-OutputCSV-'].Get() and not window_2['-OutputJSON-'].Get():
    window_2['-Submit-'].update(disabled=True)
    sg.popup('Select an output', keep_on_top=True)

You would need also code to activate Submit when you select JSON or CSV, and deactivate Submit when you deselect both elements.

    elif event_2 in ('-OutputCSV-', '-OutputJSON-'):
        if not window_2['-OutputCSV-'].Get() and not window_2['-OutputJSON-'].Get():
            window_2['-Submit-'].update(disabled=True)
            #sg.popup('Select an output', keep_on_top=True)
        else:
            window_2['-Submit-'].update(disabled=False)

Full working example:

import PySimpleGUI as sg

layout_1 = [
# things before...
    [sg.Radio('None:', "OUTPUT", default=False, key='-OutputNone-', enable_events=True)],
    [sg.Radio('CSV/JSON:', "OUTPUT", default=False, key='-OutputFile-', enable_events=True)],
    [sg.Checkbox('Output as CSV', key='-OutputCSV-', disabled=True, enable_events=True)],
    [sg.Checkbox('Output as JSON', key='-OutputJSON-', disabled=True, enable_events=True)],
    [sg.Text('Select a folder: ')], [sg.FolderBrowse(key='-Folder-')],
    [sg.Push(), sg.Column([[sg.Button("Submit", disabled=False, key='-Submit-'), sg.Cancel()]], element_justification='c'), sg.Push()]
]

window_2 = sg.Window('Info', layout_1, finalize=True)

while True:
    event_2, values_table = window_2.read()
    print(event_2)
    if event_2 in ('Cancel', 'Submit', None):
        break
    elif event_2 == '-OutputFile-':
        window_2['-OutputJSON-'].update(disabled = False)
        window_2['-OutputCSV-'].update(disabled = False)
        
        if not window_2['-OutputCSV-'].Get() and not window_2['-OutputJSON-'].Get():
            window_2['-Submit-'].update(disabled=True)
            sg.popup('Select an output', keep_on_top=True)
            
    elif event_2 == '-OutputNone-':
        window_2['-OutputJSON-'].update(disabled=True)
        window_2['-OutputCSV-'].update(disabled=True)

    elif event_2 in ('-OutputCSV-', '-OutputJSON-'):
        if not window_2['-OutputCSV-'].Get() and not window_2['-OutputJSON-'].Get():
            window_2['-Submit-'].update(disabled=True)
            #sg.popup('Select an output', keep_on_top=True)
        else:
            window_2['-Submit-'].update(disabled=False)

window_2.close()
Answered By: furas