PyQt5 QTableView添加removeRows方法后拖放选中行消失如何解决
问题原因
- 你自定义的
dropEvent处理完行移动逻辑后,依然调用了父类QTableView的dropEvent方法。父类在InternalMove模式下的默认逻辑会自动调用模型的removeRows删除被拖拽的源行,而你没有实现对应的行插入、拖拽数据写入逻辑,就会出现源行被删除、新行未添加的消失问题。 - 你在
removeRows方法中额外调用了self.layoutChanged.emit(),beginRemoveRows和endRemoveRows已经会自动发送必要的界面更新信号,多余的信号发射会引发界面状态异常。
修复方案
1. 修改myTableView的dropEvent方法
处理完自定义的垂直表头移动逻辑后,直接终止事件传播,不再调用父类的默认拖放处理:
def dropEvent(self, event): if (event.source() is not self or (event.dropAction() != Qt.MoveAction and self.dragDropMode() != QAbstractItemView.InternalMove)): super().dropEvent(event) return selection = self.selectedIndexes() from_index = selection[0].row() if selection else -1 to_index = self.indexAt(event.pos()).row() if (0 <= from_index < self.model().rowCount() and 0 <= to_index < self.model().rowCount() and from_index != to_index): header = self.verticalHeader() from_index = header.visualIndex(from_index) to_index = header.visualIndex(to_index) header.moveSection(from_index, to_index) event.accept()
2. 移除removeRows中多余的信号发射
def removeRows(self, position, rows, QModelIndex): self.beginRemoveRows(QModelIndex, position, position + rows - 1) for i in range(rows): del (self._data[position]) self.endRemoveRows() return True
效果验证
修改后选中单元格/整行拖拽时,行不会消失,Delete键删除行功能也能正常使用。如果需要拖拽调整顺序后模型内部的数据源顺序同步更新,可在moveSection操作后同步调整self.model()._data列表的顺序即可。
内容的提问来源于stack exchange,提问作者MikG
相关产品推荐
相关产品推荐

