0

(Explanation of my problem at the end)

Here is an example of a dynamic layout that add a Frame when I click on a button. Launch state of the program :

enter image description here

Then after button pressed :

enter image description here

Here is the code :

import PySimpleGUI as sg                        

def layout_for_frame(lvl_1):
    layout = [[sg.Frame(title  = 'Frame level 2',
                        layout = [[sg.Text('Text 2 '), sg.Input(key=('-level two-',lvl_1))],
                                  [sg.Combo(['A', 'B'],key=('-combo-',lvl_1))]],
                        relief = 'sunken')]]
    return layout
    
def make_window():
    layout = [[sg.Frame(title  = 'Frame level 1',
                        layout = layout_for_frame(0),
                        key    = '-Frame lvl 1-',
                        relief = 'groove')],
              [sg.Button('+',key = 'add a level two Frame')]]
    
    window = sg.Window('Window Title', layout,metadata=0)
    return window

def main():
    window = make_window()
    while True:
        event, values = window.read()
        print(event, values)
        if   event == sg.WIN_CLOSED : 
            break
        elif event == 'add a level two Frame' : 
            window.metadata += 1            
            window.extend_layout(window['-Frame lvl 1-'],(layout_for_frame(window.metadata)))
    window.close()

if __name__ == '__main__':
    main()

This works perfectly for adding a frame inside another one. The problem is adding another Frame level 1. Because I don't know how to call a function with a key without an element in the layout :

layout = [[(layout_for_frame(0),key = '-CALL FOR FRAME-')],
          [sg.Button('+',key = 'add a level one Frame')]]

This does not work, and so I can't use the same logic shown before.

My question is how to add directly a level 1 frame with a button ?

Please let me know if it is not clear, and thank you for taking the time to read through it.

0

1 Answer 1

0

Ok I figured out the answer :

It's simple really, when you call the extend window, you just let it on the main window, and then everything that is in the function, will be displayed in the main window. So you just make the Frame level 1 in the function, like so :

def layout_for_frame(lvl_1):
    layout = [[sg.Frame(title  = f'N° {lvl_1} Frame level 1',
                        layout = [[sg.Frame(title  = 'Frame level 2',
                                            layout = [[sg.Text('Text 2 '), sg.Input(key=('-level two-',lvl_1))],
                                                      [sg.Combo(['A', 'B'],key=('-combo-',lvl_1))]],
                                            relief = 'sunken')],
                                  [sg.Button('Add LVL 2 frame')]],
                        key    = ('-Frame lvl 1-',lvl_1),
                        relief = 'groove')]]
                                  
    return layout

and then when the layout becomes :

layout = [[layout_for_frame(0)],
          [sg.Button('+',key = 'add a level one Frame')]]

and for the call :

elif event == 'add a level one Frame' : 
    window.metadata += 1            
    window.extend_layout(window,(layout_for_frame(window.metadata)))

Then the result is this :

enter image description here

The only problem is the button not staying at the bottom, Would you know how to solve this ?

Sign up to request clarification or add additional context in comments.

1 Comment

Just add one sg.Column as the container for all the level-1 Frames, then it will be window.extend_layout(the_column_container, layout_for_frame(window.metadata))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.