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

QTableWidget内嵌QComboBox取值报AttributeError仅最后一行生效问题

问题原因

核心问题出在populate方法中表格填充逻辑的不合理操作,导致除最后一行外其余行的下拉框对象被意外回收/覆盖:

  • 为放置QComboBox的单元格重复设置空QTableWidgetItem:QTableWidget的同一个单元格不能同时存在Item和Cell Widget,你为1、6、7列调用setItem设置空Item的操作,会在表格刷新时覆盖/销毁已绑定的下拉框控件。
  • 重复绑定Cell Widget:你把setCellWidget操作放在下拉选项的遍历循环中,每次添加选项都重复绑定一次控件,不必要的重复操作会触发Qt内部对象管理异常。
  • 逐次修改表格行数:你每次处理一行数据就调用setRowCount逐次增加行数,会触发表格多次全局刷新,导致前面行已绑定的控件被意外回收。
  • 若你开启了表格排序功能,QTableWidget默认排序只会移动单元格Item,不会同步移动绑定的Cell Widget,也会导致索引和控件不匹配。
修复方案

按以下逻辑修改populate方法即可解决:

  1. 清空表格后一次性设置总行数,不要逐次修改行数
  2. 移除给1、6、7列设置空Item的代码,下拉框所在列不需要绑定QTableWidgetItem
  3. 下拉选项全部添加完成后,再调用一次setCellWidget绑定控件,不要放在循环内重复操作
  4. 取值时增加类型校验,避免异常崩溃

修正后的核心代码示例

def populate(self):
    self.ui.widget_unass_fights.clearContents()
    # 一次性设置总行数
    total_rows = len(x)
    self.ui.widget_unass_fights.setRowCount(total_rows)
    
    for tablerow, row in enumerate(x):
        # 普通列正常设置Item
        self.ui.widget_unass_fights.setItem(tablerow, 0, QtWidgets.QTableWidgetItem(str(row[0])))
        self.ui.widget_unass_fights.setItem(tablerow, 2, QtWidgets.QTableWidgetItem(str(row[2])))
        self.ui.widget_unass_fights.setItem(tablerow, 3, QtWidgets.QTableWidgetItem(str(row[3])))
        self.ui.widget_unass_fights.setItem(tablerow, 4, QtWidgets.QTableWidgetItem(str(row[4])))
        self.ui.widget_unass_fights.setItem(tablerow, 5, QtWidgets.QTableWidgetItem(str(row[5])))
        self.ui.widget_unass_fights.setItem(tablerow, 8, QtWidgets.QTableWidgetItem(str(row[8])))
        
        # 第1列下拉框
        combobox1 = QComboBox()
        for j in self.plane_list_combo:
            combobox1.addItem(j)
        combobox1.setCurrentText(row[1])
        # 只绑定一次控件
        self.ui.widget_unass_fights.setCellWidget(tablerow, 1, combobox1)
        
        # 第6、7列下拉框
        combobox2 = QComboBox()
        combobox2.addItem("")
        combobox3 = QComboBox()
        combobox3.addItem("")
        for j in self.pilot_list_combo:
            combobox2.addItem(j)
            combobox3.addItem(j)
        combobox2.setCurrentText(row[6])
        combobox3.setCurrentText(row[7])
        self.ui.widget_unass_fights.setCellWidget(tablerow, 6, combobox2)
        self.ui.widget_unass_fights.setCellWidget(tablerow, 7, combobox3)
    
    print(self.ui.widget_unass_fights.cellWidget(0, 1).currentText())

def update(self):
    rowcount = self.ui.widget_unass_fights.rowCount()
    for i in range(rowcount):
        flight_id = self.ui.widget_unass_fights.item(i, 0).text()
        # 增加类型校验避免报错
        combo1 = self.ui.widget_unass_fights.cellWidget(i, 1)
        flight_reg = combo1.currentText() if isinstance(combo1, QComboBox) else ""
        desc = self.ui.widget_unass_fights.item(i, 2).text()
        date = self.ui.widget_unass_fights.item(i, 3).text()
        etd = self.ui.widget_unass_fights.item(i, 4).text()
        flight_time = self.ui.widget_unass_fights.item(i, 5).text()
        combo6 = self.ui.widget_unass_fights.cellWidget(i, 6)
        pilot = combo6.currentText() if isinstance(combo6, QComboBox) else ""
        combo7 = self.ui.widget_unass_fights.cellWidget(i, 7)
        co_pilot = combo7.currentText() if isinstance(combo7, QComboBox) else ""
        max_pax = self.ui.widget_unass_fights.item(i, 8).text()

注:原代码中def update(self)行缺少冒号,属于语法错误,同步修正。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 07:06:04