You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySimpleGUI中pin函数失效:元素增删后按钮位置未自动调整

PySimpleGUI动态元素布局异常:移除Frame后按钮位置未自动调整

我开发了一个PySimpleGUI程序,通过+/-按钮添加和移除屏幕元素。原本预期使用pin函数后,元素显示变化时按钮位置会自动调整,但实际出现异常:

  • 初始状态(一切正常)
    初始状态
  • 添加Frame后(一切正常)
    添加Frame后
  • 移除Frame后,"Add another requirement"和"Remove a requirement"按钮未移动
    移除Frame后

核心布局代码

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

移除元素的窗口循环逻辑

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

补充相关函数代码

被移除的元素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 

添加Frame的逻辑代码

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)

感谢您的帮助!


内容的提问来源于stack exchange,提问作者Enrra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 02:00:53