Search code examples
python-3.xpysimplegui

Disabling button while TextInputs have not had text input into them - PySimpleGUI


I am writing a simple GUI script using PySimpleGui and have been trying for a week to figure this out, but no amount of googling or trying various solutions seems to do what I want.

The gui is simple, it has two sg.InputText inputs, and one sg.Mulitline input. There is also an sg.Button that kicks off running a function, that takes the values of the 3 inputs as its arguments, when pressed. I would like to have the button be disabled out while the user has not entered any text into the input boxes, and re-enabled once they have. This will keep the user from being able to run the tool before they enter the required inputs. I have tried basic logic, but cant seem to get it to work.

Sample Code:

import PySimpleGUI as sg

inputs_column = [
    [sg.Text(text='Enter value 1'), sg.InputText()],

    [sg.Text(text='Enter value 2'), sg.InputText()],

    [sg.Text(text='Enter values 3')],
    [sg.Multiline(size=(60, 20), sbar_background_color="grey42", key="value_list")],

    [sg.Button('Start', disabled=True), sg.Button('Quit')]
]

layout = [[sg.Column(inputs_column)]]

# Create the Window
window = sg.Window('Fancy Doo-hickey', layout)

# Event Loop to process "events" and get the "values" of the inputs
while True:
    event, values = window.read()

    # kill the process if user closes window or clicks cancel
    if event == sg.WIN_CLOSED or event == 'Quit':
        break

    # what to do when the start button is pressed
    if event == "Start":
        # turn the values given by the user input into a list
        value_list = values['value_list'].strip().splitlines()
        
        # check to see if user has given input yet
        while values[0] == '' and values[1] == '' and len(value_list) == 0:
            window['Start'].update(disabled=True)
        else:
            window['Start'].update(disabled=False)

        # run the main function
        run_function(arg1=values[0], arg2=values[1], arg3=value_list)

Any ideas? Is it even possible for PySimpleGUI to monitor what is entered into the TextInput boxes before an event is triggered?

Any help is much appreciated.


Solution

  • Need to generate an event when the content of element changed, so add one more option enable_events=True, and handle that event to decide if disable the button or not.

    Reduced code as following.

    import PySimpleGUI as sg
    
    def func(*args):
            print(*tuple(map(repr, args)))
    
    layout = [
        [sg.Input(enable_events=True, key='IN 1')],
        [sg.Input(enable_events=True, key='IN 2')],
        [sg.Multiline(size=(40, 5), enable_events=True, expand_x=True, key='IN 3')],
        [sg.Push(), sg.Button('Start', disabled=True)],
    ]
    window = sg.Window('Demo', layout)
    
    while True:
    
        event, values = window.read()
    
        if event == sg.WIN_CLOSED:
            break
    
        elif event in ('IN 1', 'IN 2', 'IN 3'):
            disabled = not (values['IN 1'] and values['IN 2'] and values['IN 3'])
            window['Start'].update(disabled=disabled)
    
        elif event == 'Start':
            func(values['IN 1'], values['IN 2'], values['IN 3'])
    
    window.close()