使 QTableView 中的项目可拖动但不可选择

Make an Item in a QTableView draggable but not selectable

一点背景知识(不是理解问题所必需的):

在我今年早些时候开发的 PySide2 应用程序中,我有一个与自定义模型一起使用的 QTableView。 可以选择其中的一些项目,然后单击按钮对所选项目执行批量操作。 其他一些项目作为数据存在的视觉指示,但执行批量操作的函数不知道如何处理它们,所以我将它们设为非选择 table。 我的程序中有另一个区域可以接受来自外部文件或来自我的 TableView 中的项目的丢弃。在这种情况下,table 中的每一项都应该能够被拖放到另一个区域。

问题:

当一个Item不被选择时table,它似乎也不可拖动。

我试过的:

代码方面不多,因为我真的不知道如何处理那个代码。 我尝试了很多Flags的组合都没有成功。

我已经用谷歌搜索和浏览 Whosebug 几个小时了,但找不到任何相关的东西,我只是被人们询问如何通过拖放重新排序 table 的帖子淹没了.

最小复制码:

from PySide2 import QtCore, QtWidgets, QtGui


class MyWindow(QtWidgets.QWidget):
    def __init__(self):
        QtWidgets.QWidget.__init__(self)
        self.setGeometry(300, 200, 570, 450)
        self.setWindowTitle("Drag Example")
        model = QtGui.QStandardItemModel(2, 1)
        table_view = QtWidgets.QTableView()

        selectable = QtGui.QStandardItem("I'm selectable and draggable")
        selectable.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsDragEnabled)
        model.setItem(0, 0, selectable)

        non_selectable = QtGui.QStandardItem("I'm supposed to be draggable, but I'm not")
        non_selectable.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsDragEnabled)
        model.setItem(1, 0, non_selectable)

        table_view.setModel(model)
        table_view.setDragDropMode(table_view.DragOnly)
        layout = QtWidgets.QVBoxLayout(self)
        layout.addWidget(table_view)
        self.setLayout(layout)


app = QtWidgets.QApplication([])
win = MyWindow()
win.show()
app.exec_()

有没有人对如何使项目启用拖动但禁用选择有建议?

谢谢

我找到了一个解决方法,虽然不一定是完美的答案,但它对我有用。

我没有使项目无法 select,而是使用自定义数据角色在 select 处理它时使它在视觉上看起来不像 select。

我在批量函数中使用相同的数据标志来过滤掉 select离子。

为了让项目看起来像没有 selected,即使它们是,我使用了自定义样式的项目委托:

class MyDelegate(QtWidgets.QStyledItemDelegate):
    def __init__(self, parent=None):
        super(MyDelegate, self).__init__(parent)

    def paint(self, painter, option, index):

        if option.state & QtWidgets.QStyle.State_Selected:
            if index.data(Qt.UserRole) == 2:  # Some random flag i'm using
                text_brush = option.palette.brush(QtGui.QPalette.Text)
                if index.row() % 2 == 0:
                    bg_brush = option.palette.brush(QtGui.QPalette.Base)
                else:
                    bg_brush = option.palette.brush(QtGui.QPalette.AlternateBase)
                # print brush
                option.palette.setBrush(QtGui.QPalette.Highlight, bg_brush)
                option.palette.setBrush(QtGui.QPalette.HighlightedText, text_brush)

        super(MyDelegate, self).paint(painter, option, index)

并且在 table 我设置:

delegate = MyDelegate()
table_view.setItemDelegate(delegate)

我从这个post改编了这个解决方案: