如何在PyQt5开发的卡路里计数APP中实现动态增删输入组件
PyQt5 动态增删商品组件实现方案
实现思路
- 新增专门的垂直布局容器存放所有动态生成的商品行,避免和固定控件(表头、操作按钮)冲突
- 用类属性列表维护所有动态生成的组件引用,方便删除时定位和释放资源
- 新增行时批量创建对应组件插入容器布局,删除行时从布局和维护列表中移除最后一行组件并销毁
代码修改
主程序代码
import sys from PyQt5.QtWidgets import * from PyQt5 import uic from PyQt5 import QtWidgets class MyWin(QtWidgets.QMainWindow): def __init__(self): QtWidgets.QMainWindow.__init__(self) uic.loadUi("gui.ui", self) # 维护动态生成的商品行列表 self.product_rows = [] # 绑定按钮点击事件 self.add_product.clicked.connect(self.add_product_row) self.remove_product.clicked.connect(self.remove_product_row) # 调整UI结构:新增专门放商品行的容器布局 self.product_container = QVBoxLayout() # 把原有默认的第一行输入框移到容器中(可选,保留初始行) self.product_container.addLayout(self.horizontalLayout) # 调整布局层级,把容器插入到间隔符上方 self.verticalLayout_2.removeItem(self.verticalSpacer) self.verticalLayout_2.insertLayout(2, self.product_container) self.verticalLayout_2.addSpacerItem(self.verticalSpacer) def add_product_row(self): # 新建水平布局承载当前行的组件 row_layout = QHBoxLayout() # 按需求创建组件:如果需要每一行都带标签,可在这里新增两个QLabel加入布局 product_input = QLineEdit() weight_input = QLineEdit() # 组件加入行布局 row_layout.addWidget(product_input) row_layout.addWidget(weight_input) # 行布局加入全局容器 self.product_container.addLayout(row_layout) # 当前行信息存入维护列表 self.product_rows.append((row_layout, product_input, weight_input)) def remove_product_row(self): # 可加判断if len(self.product_rows) <= 1: return 限制至少保留一行 if not self.product_rows: return # 取出最后一行并销毁资源 row_layout, product_input, weight_input = self.product_rows.pop() product_input.deleteLater() weight_input.deleteLater() # 清空布局后销毁布局 while row_layout.count(): item = row_layout.takeAt(0) if item.widget(): item.widget().deleteLater() row_layout.deleteLater() if __name__ == '__main__': app = QApplication(sys.argv) mw = MyWin() mw.show() sys.exit(app.exec_())
可选UI优化
如果不想在代码里调整布局结构,可以直接修改gui.ui文件,在表头行和间隔符之间新增一个空的QVBoxLayout,命名为product_container,即可省略代码中调整布局层级的步骤。
扩展说明
- 所有动态生成的输入框内容可以遍历
self.product_rows列表批量读取,方便后续计算卡路里 - 如果需要支持单独删除某一行,只需要在生成行的时候给每一行加一个删除按钮,绑定对应行的销毁逻辑即可
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

