PyQt QTableView编辑pandas加载的CSV单元格触发IndexError问题咨询
错误原因
- 核心混淆点:
self._df.values返回的是numpy二维数组,仅支持整数、切片、布尔数组等类型作为索引;但你代码中通过row = self._df.index[index.row()]获取的是Pandas DataFrame的行标签,通过col = self._df.columns[index.column()]获取的是DataFrame的列名,当行标签非整数、或者列名为字符串时,将这些值传入numpy数组作为索引就会触发该报错。 - 扩展异常场景:即使行标签是整数,若后续执行过排序、筛选等操作导致行索引不连续,也会出现索引越界问题。
修复方案
仅需修改PandasModel_1类的setData方法即可,以下两种实现方案二选一:
方案1:直接操作numpy数组(和原有data方法逻辑一致,改动最小)
直接使用QModelIndex自带的整数位置索引操作数组,同时增加类型转换逻辑避免修改后数据类型错乱:
def setData(self, index, value, role): if not index.isValid() or role != Qt.EditRole: return False try: # 转换输入值的类型和原列数据类型保持一致 target_type = self._df.dtypes[index.column()].type converted_value = target_type(value) # 直接用整数位置索引操作numpy数组 self._df.values[index.row()][index.column()] = converted_value self.dataChanged.emit(index, index) return True except: # 类型转换失败则不修改数据 return False
同时可以删除原方法中无用的row = self._df.index[index.row()]、col = self._df.columns[index.column()]两行冗余代码。
方案2:直接操作Pandas DataFrame(适配性更强)
用Pandas原生的位置索引iloc操作,避免直接接触numpy数组的索引规则,后续对DataFrame做排序、筛选等操作时不需要额外适配:
def setData(self, index, value, role): if not index.isValid() or role != Qt.EditRole: return False try: self._df.iloc[index.row(), index.column()] = value self.dataChanged.emit(index, index) return True except: return False
额外优化建议
你当前loadFile方法中每次加载CSV文件都会重复给save_file_btn_1绑定Event1槽函数,会导致点击按钮时触发多次执行,建议将该绑定逻辑移到Main类的__init__方法中,仅执行一次即可。
内容的提问来源于stack exchange,提问作者Pino Villa
相关产品推荐
相关产品推荐

