0

I have a pop-up with a user input field using PySimpleGUI. If the user types the wrong input I want to show some text beneath the input field saying that they need to type it in again. My idea this far is the code below:

def start_pop_up(self, wrong_answer=False):
    sg.theme('DarkAmber')
    if wrong_answer:
        layout = wrong_answer
    else:
        layout = initial

    window = sg.Window('Please chose start settings', layout)
    event, values = window.read()

    if values['user_input']:
        if test_user_input:
            # Set some parameters accordingly .....
            pass
        else:
            window.close()
            self.start_pop_up(True)

    window.close()

Where my layouts looks like this:

initial = [[sg.Text('User input: ', size=(15, 1)), sg.InputText(size=(60, 1), key='user_input')],
           [sg.Submit()]]

wrong_answer = [[sg.Text('User input: ', size=(15, 1)), sg.InputText(size=(60, 1), key='user_input')],
                [sg.Text('Wrong input, please input the correct answer.', text_color='red')],
                [sg.Submit()]]

If I input the wrong format then the correct window shows up. But if I try to put in the wrong answer again then I get this error:

How can I solve this?

Eli
  • 156
  • 8

1 Answers1

0

Problem solved, but it is a strange behaviour which might be a bug.

Instead of first creating the layouts as variables I put them immediately in the layout if/else statements like this:

if wrong_answer:
    layout = [[sg.Text('User input: ', size=(15, 1)), sg.InputText(size=(60, 1), key='user_input')],
              [sg.Text('Wrong input, please input the correct answer.', text_color='red')],
              [sg.Submit()]]
else:
    layout = [[sg.Text('User input: ', size=(15, 1)), sg.InputText(size=(60, 1), key='user_input')],
              [sg.Submit()]]

And now it worked correctly. Seems like PySimpleGUI needs to "re-initialize" the layouts by printing them out like this.

Eli
  • 156
  • 8
  • 1
    You were re-using the same layout over and over. The contents of `initial` never changed. It always held the exact same elements if you defined it only once. The new if statements are making a new layout rather than re-using one previously defined. – Mike from PSG Nov 21 '20 at 16:33
  • 1
    As the popup-error window states, print the layout you're using each time. You'll see that the exact same objects are used. The same id/address in memory will be shown for the elements each time you print it. If you only execute a statement once that creates an object, you only have 1 of those objects. One way this is overcome is using a function that returns a layout, then that would be a new copy every time it is called. – Mike from PSG Nov 21 '20 at 16:44
  • Well I want to use the same layout each time a certain case happens. But it says I can't, which seems like a weird feature/bug :) – Eli Nov 22 '20 at 08:17
  • It's like settings x=5. Then later expecting x to point to a different 5. It's the same 5. – Mike from PSG Nov 22 '20 at 16:35
  • @MikeyB, I hear what you are saying. For me it sounds more like I can only use x one time and then it is "used up". Which is a strange behaviour. Thank you for the input, I got it to work eventually :) – Eli Nov 22 '20 at 18:21
  • Yes, you can use x one time, and then it's "used up". You can't re-use objects that have been used to create a window. All of the member variables point to the old window. You need a new object to use. You are creating objects when you make a layout. Button() makes a button object. You need a new Button object to go into a new window. – Mike from PSG Nov 23 '20 at 20:00