Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to display different layouts based on button clicks in PySimple GUI? (Persistent window loop)

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
like image 384
nsquires Avatar asked Dec 22 '22 20:12

nsquires


1 Answers

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.

like image 138
Mike from PSG Avatar answered Dec 31 '22 04:12

Mike from PSG