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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 22:39:01