PyQt5基于QSqlTableModel的QTableView如何获取所有勾选多行数据
前置修正
原有代码存在两处语法错误,需先调整:
RealMainWindow类中def selected(self):前的多余空格,对齐为和__init__同级的类方法缩进- 数据库连接判断逻辑下的
sys.exit(1)缺少缩进,修正为:
if not createConnection(): sys.exit(1)
问题根源
你混淆了两类“选中”逻辑,导致现有获取逻辑完全无效:
QTableView内置的高亮选择(由selectionModel管理,仅响应鼠标点击单元格操作,和你自定义的复选框无关联)- 你在
TableModel中手动维护的复选框勾选状态(存储在checkeable_data字典中)
你当前用 selectionModel 获取的是鼠标点击过的行,不是复选框勾选的行,因此才会出现「取消复选框仍被判定选中」、「无法批量获取所有勾选行」的问题。
解决方案
1. 新增最多5行的勾选校验
修改 TableModel 的 setData 方法,限制最大勾选数量为5:
def setData(self, index, value, role=Qt.EditRole): if role == Qt.CheckStateRole and ( self.flags(index) & Qt.ItemIsUserCheckable != Qt.NoItemFlags ): # 勾选前校验已勾选数量 if value == Qt.Checked: current_checked = sum(1 for state in self.checkeable_data.values() if state == Qt.Checked) if current_checked >= 5: return False # 超过5行禁止勾选 self.checkeable_data[index.row()] = value self.dataChanged.emit(index, index, (role,)) return True return QSqlTableModel.setData(self, index, value, role)
2. 重写数据获取逻辑
不再依赖 selectionModel,直接遍历 checkeable_data 提取所有勾选的行号,再批量取对应字段值,修正后的 selected 方法:
def selected(self): # 收集所有复选框勾选的行号 checked_rows = [row for row, state in self.model.checkeable_data.items() if state == Qt.Checked] # 批量获取NAME字段 name_list = [self.model.record(row).value("NAME") for row in checked_rows] # 输出结果 print("勾选的NAME字段列表:", name_list)
额外优化提示
如果后续需要给表格加排序/筛选功能,建议把 checkeable_data 的键从行号换成表的主键ID(比如ID字段),避免 QSqlTableModel 重新执行 select() 后行号错位,导致勾选状态和行不匹配。
内容的提问来源于stack exchange,提问作者Sudipto21
相关产品推荐
相关产品推荐

