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

PYQT5如何访问父布局内动态生成的子布局对应的控件内容

问题核心原因

你每次调用createLayout_groupbox_SP创建端口组时,都会把新生成的QGroupBox、内部布局、控件都赋值给self的同名实例属性,后续创建的内容会直接覆盖之前的属性值,因此self.layout_in_groupbox_SP永远指向最后一次创建的内部布局,自然只能读取到最后一组端口的控件数据。


方案1:直接通过布局层级访问(无需额外存储)

你可以直接通过layout_SArea_SP的层级关系逐层获取指定位置的控件,无需修改现有创建逻辑,示例实现如下:

# 封装通用获取控件的方法
def get_port_widget(self, port_index, widget_index):
    # port_index: 要访问的端口组序号,从0开始计数
    # widget_index: 组内控件序号,0=端口类型下拉框,1=端口号输入框,2=端口名输入框,3=untagged vlan输入框,4=tagged vlan输入框
    port_group_box = self.layout_SArea_SP.itemAt(port_index).widget()
    group_inner_layout = port_group_box.layout()
    return group_inner_layout.itemAt(widget_index).widget()

# 调用示例
def exemple_commands(self):
    # 获取第1个端口组(序号0)的端口类型下拉框当前值
    print(self.get_port_widget(0, 0).currentText())
    # 获取第3个端口组(序号2)的端口名输入框内容
    print(self.get_port_widget(2, 2).text())

方案2:主动存储所有端口控件引用(访问更直观)

如果不想每次都遍历布局层级,可以新增一个列表存储所有端口组的控件引用,访问时可以直接通过索引+字段名读取,修改逻辑如下:

  1. 先在类的__init__方法中新增存储控件的列表:
def __init__(self):
    # 原有初始化逻辑不变,新增下面一行
    self.port_widget_list = []
  1. 修改createLayout_groupbox_SP方法,不把控件赋值给self全局属性,而是存入列表:
def createLayout_groupbox_SP(self, number):
    groupbox_SP = QtWidgets.QGroupBox("Port-{}:".format(number), self)
    layout_in_groupbox_SP = QtWidgets.QHBoxLayout(groupbox_SP)
    # 把当前端口组的所有控件存在字典里,不绑定到self全局属性
    current_port_widgets = {
        "type_combo": QtWidgets.QComboBox(groupbox_SP),
        "num_input": QtWidgets.QLineEdit(groupbox_SP),
        "name_input": QtWidgets.QLineEdit(groupbox_SP),
        "untagged_vlan": QtWidgets.QLineEdit(groupbox_SP),
        "tagged_vlan": QtWidgets.QLineEdit(groupbox_SP)
    }
    current_port_widgets["type_combo"].addItems(list_type_ports)
    current_port_widgets["num_input"].setFixedSize(20,20)
    # 控件添加到布局的逻辑不变
    layout_in_groupbox_SP.addWidget(current_port_widgets["type_combo"])
    layout_in_groupbox_SP.addWidget(current_port_widgets["num_input"])
    layout_in_groupbox_SP.addWidget(current_port_widgets["name_input"])
    layout_in_groupbox_SP.addWidget(current_port_widgets["untagged_vlan"])
    layout_in_groupbox_SP.addWidget(current_port_widgets["tagged_vlan"])
    # 当前端口控件字典存入全局列表
    self.port_widget_list.append(current_port_widgets)
    return groupbox_SP
  1. 修改删除端口的方法,同步删除列表中对应的数据:
def dell_ports(self):
    import sip
    if self.layout_SArea_SP.count() > 0: 
        sip.delete(self.layout_SArea_SP.itemAt(self.layout_SArea_SP.count()-1).widget())
        # 同步删除列表最后一项
        self.port_widget_list.pop()
  1. 之后访问控件时可以直接用索引+字段名读取,逻辑更清晰:
def exemple_commands(self):
    # 获取第1个端口组的端口类型值
    print(self.port_widget_list[0]["type_combo"].currentText())
    # 获取第2个端口组的tagged vlan值
    print(self.port_widget_list[1]["tagged_vlan"].text())

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 09:39:01