I am wondering if there is a way that I can manage different layouts based on button clicks in PySimple GUI. I am just starting off using this framework and I want to find the best way of navigating menus. Doesn't have to be using different layouts but this just struck me of the most intuitive way of doing it.
I was thinking like maybe having a list of layouts that get pushed to the top when a certain submenu button is selected.
layouts = [layout1, layout2, layout3, layout4]
Or maybe start the program with:
layout = layout1
And when a submenu is selected just change the state to:
layout = layout2
So for example having a 'Main Menu' layout, and upon a button click, bringing a different layout, or 'submenu', to the 'front' so that the entire program runs in one single window. Maybe looking something like this:
Main Menu
Button 1
Button 2
Button 3
When Button 1 is clicked, the window stays open, but the display changes to Submenu 1.
From the PySimpleGui Docs, I am using the persistent window loop that it is recommended for structuring some programs:
import PySimpleGUI as sg
sg.theme('BluePurple')
layout = [[sg.Text('Your typed chars appear here:'), sg.Text(size=(15,1), key='-OUTPUT-')],
[sg.Input(key='-IN-')],
[sg.Button('Show'), sg.Button('Exit')]]
window = sg.Window('Pattern 2B', layout)
while True: # Event Loop
event, values = window.read()
print(event, values)
if event in (None, 'Exit'):
break
if event == 'Show':
# Update the "output" text element to be the value of "input" element
window['-OUTPUT-'].update(values['-IN-'])
window.close()
I am open to changing the structure entirely but I wanted to get the menu navigation down before I start building the functionality.
- Using PySimpleGUI==4.14.1
You're actually very close.
Here is what I think you're looking for. What you need to do is add your layouts to Column elements. Then make all columns invisible except for the one you want visible.
This is a great idea.
import PySimpleGUI as sg
# ----------- Create the 3 layouts this Window will display -----------
layout1 = [[sg.Text('This is layout 1 - It is all Checkboxes')],
*[[sg.CB(f'Checkbox {i}')] for i in range(5)]]
layout2 = [[sg.Text('This is layout 2')],
[sg.Input(key='-IN-')],
[sg.Input(key='-IN2-')]]
layout3 = [[sg.Text('This is layout 3 - It is all Radio Buttons')],
*[[sg.R(f'Radio {i}', 1)] for i in range(8)]]
# ----------- Create actual layout using Columns and a row of Buttons
layout = [[sg.Column(layout1, key='-COL1-'), sg.Column(layout2, visible=False, key='-COL2-'), sg.Column(layout3, visible=False, key='-COL3-')],
[sg.Button('Cycle Layout'), sg.Button('1'), sg.Button('2'), sg.Button('3'), sg.Button('Exit')]]
window = sg.Window('Swapping the contents of a window', layout)
layout = 1 # The currently visible layout
while True:
event, values = window.read()
print(event, values)
if event in (None, 'Exit'):
break
if event == 'Cycle Layout':
window[f'-COL{layout}-'].update(visible=False)
layout = layout + 1 if layout < 3 else 1
window[f'-COL{layout}-'].update(visible=True)
elif event in '123':
window[f'-COL{layout}-'].update(visible=False)
layout = int(event)
window[f'-COL{layout}-'].update(visible=True)
window.close()
[EDIT]
A new Demo Program was added to the PySimpleGUI GitHub named "Demo_Column_Elem_Swap_Entire_Window.py". You can see the code and run it in your browser by visiting Trinket.
Using Google
I found that there is no method to replace one layout with another.
PySimpleGUI Issues
: Updating form layouts #117,
You can only create all elements in one layout and some of them hide and show again:
Reddit r/PySimpleGUI
: Is it possible to update the layout of a column / frame?
In tkinter
there is popular method to use Frame
to group widgets and later hide/show frames to change content in window. It seems PySimpleGUI
has also Frame
but I don't have example which would work as I expected.