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:主动存储所有端口控件引用(访问更直观)
如果不想每次都遍历布局层级,可以新增一个列表存储所有端口组的控件引用,访问时可以直接通过索引+字段名读取,修改逻辑如下:
- 先在类的
__init__方法中新增存储控件的列表:
def __init__(self): # 原有初始化逻辑不变,新增下面一行 self.port_widget_list = []
- 修改
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
- 修改删除端口的方法,同步删除列表中对应的数据:
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()
- 之后访问控件时可以直接用索引+字段名读取,逻辑更清晰:
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
相关产品推荐
相关产品推荐

