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

PyQt 6.9:含隐藏列的QTableView行拖拽排序异常问题咨询

QTableView行拖拽重排:隐藏列0引发的功能异常问题

问题背景

开发基于QTableView的应用,需实现行拖拽重排功能。升级至PyQt 6.9并参考方案后,最小测试示例满足两个核心需求:

  • 仅允许在现有行之间、首行之前或末行之后拖放行,禁止通过拖放覆盖已有行;
  • 拖放行始终插入到列0位置,避免列偏移导致模型/视图新增列。

异常表现

将功能移植到正式应用时,因隐藏列0出现以下问题:

  1. 表格拖放指示器(dropIndicator)无法在行间正确显示;
  2. 拖放行后,被移动行的列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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 10:14:50