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

PyQt5中QTableWidget内按钮与输入框关联功能异常求助

问题分析与修复方案

核心问题原因

你的代码中,boxlayout类里的le和btn被定义为类属性(直接绑定在boxlayout类上),而非实例属性(绑定在self上)。类属性会被所有实例共享,每次创建新的boxlayout实例时,都会覆盖掉之前的le和btn引用。这就导致所有按钮最终都指向最后一个创建的QLineEdit,所以点击任意按钮都会修改最后一个输入框的内容。

修复后的完整代码

from PyQt5.QtWidgets import (
    QMainWindow,
    QApplication,
    QPushButton,
    QFileDialog,
    QGridLayout,
    QLineEdit,
    QTableWidget,
    QHBoxLayout,
    QWidget,
)
from PyQt5.QtCore import pyqtSlot
import sys
from functools import partial

class BoxLayout(QWidget):
    def __init__(self):
        super().__init__()
        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        # 改为实例属性,每个实例拥有独立的le和btn
        self.le = QLineEdit()
        self.btn = QPushButton("选择文件")
        layout.addWidget(self.le)
        layout.addWidget(self.btn)
        self.setLayout(layout)

class Main(QMainWindow):
    def __init__(self):
        super().__init__()
        centralWidget = QWidget()
        self.setCentralWidget(centralWidget)
        mainlayout = QGridLayout(centralWidget)
        self.table = QTableWidget(self)
        self.table.resize(640, 480)
        self.table.setColumnCount(3)
        self.table.setRowCount(4)
        mainlayout.addWidget(self.table)
        save_button = QPushButton('保存路径')
        mainlayout.addWidget(save_button)
        save_button.clicked.connect(self.save_as_list)
        
        # 创建单元格组件并绑定事件
        for i in range(4):
            for j in range(3):
                cell_widget = BoxLayout()
                self.table.setCellWidget(i, j, cell_widget)
                # 绑定当前实例的按钮和输入框
                cell_widget.btn.clicked.connect(partial(self.open_dialog, cell_widget.le))

    @pyqtSlot(QLineEdit)
    def open_dialog(self, le: QLineEdit):
        file_name = QFileDialog.getOpenFileName(
            self,
            "选择文件",
            "${HOME}",
            "所有文件 (*)",
        )
        le.setText(file_name[0])

    def save_as_list(self):
        # 每次保存前清空列表,避免累积旧数据
        self.list_C = []
        for i in range(4):
            for j in range(3):
                cell_widget = self.table.cellWidget(i, j)
                item = cell_widget.le.text()
                self.list_C.append(item)  
        print(self.list_C)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    main_gui = Main()
    main_gui.show()
    sys.exit(app.exec())

关键修改点

  • 将类属性改为实例属性:在BoxLayout类中,把boxlayout.le和boxlayout.btn改为self.le和self.btn,确保每个单元格组件都拥有独立的输入框和按钮。
  • 正确绑定事件:创建每个BoxLayout实例后,直接引用该实例的btn和le进行事件绑定,避免指向共享的类属性。
  • 优化路径存储:移除全局变量list_C,改为Main类的实例属性self.list_C,并在每次保存前清空,防止重复添加旧数据。
  • 代码规范优化:将类名boxlayout改为BoxLayout(遵循Python大驼峰命名规范),给按钮添加文本"选择文件"提升可用性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 22:09:19