I have a program adding and removing elements on the screen with + and - buttons, the problem is the fact that these buttons don't change position automatically after this change of display like I would expect when using pin function :
1- Initial situation (everything is fine)
2- Adding a frame (everything is fine)
3- Removing a frame (the buttons 'Add another requirement' and 'Remove a requirement' did not move)
Code for this layout :
def layout_specification_frame(lvl_1,lvl_2):
layout = [[sg.Frame(title = f'Specification N° {lvl_1}',
layout = [[sg.Text ('Name of the specification'), # Layout for one specification
sg.Input(key = ('-SPECIFICATION TITLE-', lvl_1)),
sg.Text ('Select IFC Version:'),
sg.Combo(ifc_versions, size=(20, 1),default_value='IFC4', key=('-VERSION-',lvl_1))],
[sg.Frame(title = 'Applicability',
layout = [[sg.Text ('All elements of'),
sg.Combo (categories, default_value=None, enable_events=True, key=('-FACET-',lvl_1)),
sg.Text ('That have a')],
[sg.Column(layout_parameter(category,lvl_1),key = f'-FACET PARAMETERS {lvl_1}-')]],
key = f'-APPLICABILITY {lvl_1}-',
relief = 'sunken')],
[sg.Column(layout_requirement_frame(lvl_1,lvl_2),key = f'-SPEC REQUIREMENT {lvl_1}-')],
[sg.pin(sg.Column([[sg.Button('Add another requirement', key = ('-ADD REQ-',lvl_1)),
sg.Button('Remove a requirement',key = ('-REMOVE REQ-',lvl_1))]]))]],
key = ('-FRAME LVL 1-',lvl_1),
relief = 'groove')]]
return layout
and in the window.read loop :
elif event[0] == '-REMOVE REQ-' :
lvl_2 = lvl_counter[event[1]]
if lvl_2 >1:
window[f'-REQUIREMENT {event[1],lvl_2}-'].update(visible = False)
lvl_counter.update({event[1]:lvl_2-1})
window.refresh()
Thank you for your time
Update to answer comments : (the code is quite big so I did not want to overload)
The element corresponding to this
window[f'-REQUIREMENT {event[1],lvl_2}-'].update(visible = False)
is in the function called sg.Column(layout_requirement_frame(lvl_1,lvl_2),key = f'-SPEC REQUIREMENT {lvl_1}-')
That function is described here : (I also add the other function called inside so you can follow)
def layout_requirement_frame(lvl_1,lvl_2):
layout = [[sg.Frame(title = f'Requirement {lvl_2}',
layout = [[sg.Text ('Should have a '),
sg.Combo(categories_req, default_value=None, enable_events=True, key=('-FACET REQ-',lvl_1,lvl_2)),
sg.Text ('With')],
[sg.Column(layout_parameter_req(category_req,lvl_1,lvl_2),key = f'-REQ FACET PARAMETERS {lvl_1, lvl_2}-')]],
key = f'-REQUIREMENT {lvl_1,lvl_2}-',
relief = 'sunken')]]
return layout
def layout_parameter_req(category_req,lvl_1,lvl_2):
cat = category_req[(lvl_1,lvl_2)]
if cat == None :
layout = [[]]
else :
items = Facets[cat]['facet_parameters']
layout = [[sg.pin(sg.Frame(title = '',
layout = [[sg.Text (item['name'], size=(15, 1)),
sg.Input (key = ('req',cat, item['name'],lvl_1,lvl_2)),
sg.Text ('Required' if item['required'] else 'Optional',font=('Helvetica', 12, 'bold' if item['required'] else '')),
sg.Push (),
sg.Button('+')]for item in items],
key = f'- FRAME REQ{cat,lvl_1,lvl_2}-',
relief = 'flat'))]]
return layout
And the frame is added with an extend layout just there :
elif event[0] == '-ADD REQ-' :
categories_req = categories.copy()
if values[('-FACET-',event[1])]:
categories_req.remove(values[('-FACET-',event[1])])
lvl_2 = lvl_counter[event[1]]+1 #retrieve the previous value (with the dict)
category_req.update({(event[1],lvl_2):None})
if f'-REQUIREMENT {event[1],lvl_2}-' in window.AllKeysDict:
window[f'-REQUIREMENT {event[1],lvl_2}-'].update(visible = True)
lvl_counter.update({event[1]:lvl_2})
else :
lvl_counter.update({event[1]:lvl_2})
window.extend_layout(window[f'-SPEC REQUIREMENT {event[1]}-'],layout_requirement_frame(event[1],lvl_2))
window[('-FACET REQ-',event[1],lvl_2)].update(values=categories_req)
I cannot run your script to find what's wrong, but reduce and revise your code to following script and it work.
import PySimpleGUI as sg
def layout_specification_frame(lvl_1,lvl_2):
sub_frame = [
[sg.Text('All elements of'),
sg.Text ('That have a')],
[sg.Column([],key = f'-FACET PARAMETERS {lvl_1}-')],
]
column_layout = [
[sg.Button('Add another requirement', key = ('-ADD REQ-',lvl_1)),
sg.Button('Remove a requirement',key = ('-REMOVE REQ-',lvl_1))],
]
frame_layout = [
[sg.Text ('Name of the specification'),
sg.Input(key=('-SPECIFICATION TITLE-', lvl_1)),
sg.Text ('Select IFC Version:')],
[sg.Frame('Applicability', sub_frame, key=f'-APPLICABILITY {lvl_1}-', relief = 'sunken')],
[sg.Column(layout_requirement_frame(lvl_1,lvl_2),key = f'-SPEC REQUIREMENT {lvl_1}-')],
[sg.pin(sg.Column(column_layout))]],
layout = [[sg.Frame(f'Specification N° {lvl_1}', frame_layout, key=('-FRAME LVL 1-',lvl_1), relief='groove')]]
return layout
def layout_requirement_frame(lvl_1,lvl_2):
frame_layout = [
[sg.Text ('Should have a '),
sg.Text ('With')],
[sg.Column(layout_parameter_req(lvl_1,lvl_2),key=f'-REQ FACET PARAMETERS {lvl_1, lvl_2}-')],
]
layout = [[sg.pin(sg.Frame(f'Requirement {lvl_2}', frame_layout, key=f'-REQUIREMENT {lvl_1,lvl_2}-', relief = 'sunken'))]]
return layout
def layout_parameter_req(lvl_1,lvl_2):
items = []
frame_layout = [
[sg.Text(item, size=(15, 1)),
sg.Input(key=('req', item, lvl_1, lvl_2)),
sg.Text('Required'), sg.Push(), sg.Button('+')]
for item in items
]
layout = [[sg.pin(sg.Frame('', frame_layout, key=f'- FRAME REQ{lvl_1,lvl_2}-', relief='flat'))]]
return layout
lvl_1, lvl_2 = 1, 1
layout = layout_specification_frame(lvl_1,lvl_2)
window = sg.Window("Window Title", layout)
while True:
event, values = window.read()
if event == sg.WIN_CLOSED:
break
elif event[0] == '-ADD REQ-' :
lvl_2 += 1
if f'-REQUIREMENT {lvl_1,lvl_2}-' in window.AllKeysDict:
window[f'-REQUIREMENT {lvl_1,lvl_2}-'].update(visible=True)
else :
window.extend_layout(window[f'-SPEC REQUIREMENT {lvl_1}-'],layout_requirement_frame(lvl_1,lvl_2))
elif event[0] == '-REMOVE REQ-' :
if lvl_2 > 1:
window[f'-REQUIREMENT {lvl_1,lvl_2}-'].update(visible=False)
lvl_2 -= 1
window.close()