PyQt 6.9:含隐藏列的QTableView行拖拽排序异常问题咨询
QTableView行拖拽重排:隐藏列0引发的功能异常问题
问题背景
开发基于QTableView的应用,需实现行拖拽重排功能。升级至PyQt 6.9并参考方案后,最小测试示例满足两个核心需求:
- 仅允许在现有行之间、首行之前或末行之后拖放行,禁止通过拖放覆盖已有行;
- 拖放行始终插入到列0位置,避免列偏移导致模型/视图新增列。
异常表现
将功能移植到正式应用时,因隐藏列0出现以下问题:
- 表格拖放指示器(dropIndicator)无法在行间正确显示;
- 拖放行后,被移动行的列0数据丢失,其余列数据整体前移。
临时替代方案
将原列0的数据存入索引的其他角色,而非通过隐藏列实现数据隐藏。
复现代码
取消第21行的注释即可复现问题:
import sys from PyQt6.QtCore import Qt from PyQt6.QtGui import QStandardItemModel, QStandardItem from PyQt6.QtWidgets import (QApplication, QMainWindow, QTableView, QAbstractItemView, QWidget, QVBoxLayout, QPushButton) class MainWindow(QMainWindow): def __init__(self): super().__init__() self.central_widget = QWidget() self.setCentralWidget(self.central_widget) self.central_widget.setLayout(QVBoxLayout()) self.table = QTableView() self.central_widget.layout().addWidget(self.table) self._config_table() self.model = self._make_model() self.table.setModel(self.model) self.table.resizeRowsToContents() self.table.resizeColumnsToContents() #self.table.hideColumn(0) self.button = QPushButton("Check") self.central_widget.layout().addWidget(self.button) self.button.clicked.connect(self._log_model_contents) self.show() def _config_table(self): self.table.setDragDropMode(QAbstractItemView.DragDropMode.InternalMove) self.table.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows) self.table.setDragEnabled(True) self.table.setAcceptDrops(True) self.table.setDropIndicatorShown(True) self.table.setDragDropOverwriteMode(False) def _make_model(self): data = [ [1, 2, 3, 4, 5], ["a", "b", "c", "d", "e"], [5.2, 5.3, 5.4, 5.5, 5.6], [0, 0, None, 0, 9999] ] model = MyModel(0, 5) for r in data: items_row = list(map(lambda x: QStandardItem(str(x) if x is not None else None), r)) for item in items_row: item.setFlags(Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsDragEnabled | Qt.ItemFlag.ItemIsEditable) model.appendRow(items_row) return model def _log_model_contents(self): for r in range(0, self.model.rowCount()): row_data = [] for c in range(0, self.model.columnCount()): row_data.append(self.model.index(r, c).data(Qt.ItemDataRole.DisplayRole)) print(r, row_data) class MyModel(QStandardItemModel): def dropMimeData(self, data, action, row, column, parent): return super().dropMimeData(data, action, row, 0, parent) app = QApplication([]) my_window = MainWindow() sys.exit(app.exec())
核心疑问
希望明确隐藏列0为何会破坏原有拖拽重排功能的底层原因。
内容的提问来源于stack exchange,提问作者mikstravaganza
相关产品推荐
相关产品推荐

