无法在 PysimpleGUI 中固定功能

问题描述 投票:0回答:1

我有一个程序使用 + 和 - 按钮在屏幕上添加和删除元素,问题是这些按钮在显示更改后不会自动更改位置,就像我在使用 pin 功能时所期望的那样:

1- 初始情况(一切都很好)

2- 添加框架(一切都很好)

3- 删除框架(“添加另一个要求”和“删除要求”按钮未移动)

此布局的代码:

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

并在 window.read 循环中:

        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()

感谢您的宝贵时间

更新回答评论:(代码相当大,所以我不想超载)

与this对应的元素

window[f'-REQUIREMENT {event[1],lvl_2}-'].update(visible = False)

位于名为

sg.Column(layout_requirement_frame(lvl_1,lvl_2),key = f'-SPEC REQUIREMENT {lvl_1}-')

的函数中

该函数在这里描述:(我还添加了内部调用的其他函数,以便您可以遵循)


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 

框架添加了扩展布局:

 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)
python pysimplegui
1个回答
0
投票

我无法运行你的脚本来找出问题所在,但将你的代码减少并修改为以下脚本并且它可以工作。

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.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()

© www.soinside.com 2019 - 2024. All rights reserved.