在拖放中保留 QStandardItem 子类

Preserve QStandardItem subclasses in drag and drop

我有:

self.treeView = QTreeView()
self.treeView.setObjectName("testView")
self.treeView.setDragDropMode(QAbstractItemView.InternalMove)
self.treeView.setSelectionMode(QAbstractItemView.ExtendedSelection)

itemA = SubclassQStandardItemA(self)
itemB = SubcalssQStandardItemB(self)

self.model = QStandardItemModel()
self.treeView.setModel(self.model)

self.model.appendRow(itemA)
self.model.appendRow(itemB)

当我将 itemB 移动到 itemA 并检查其 class 时,ItemB 不再是 SubclassQStandardItemB,而是 QStandardItem。

如何在拖放时保持项目的原始class?

, you can use setItemPrototype to provide an item factory for a model. However, as also stated in the answer, only certain kinds of information are transferred during a drag and drop operation. For a QStandardItem, this means only the item flags and item data 中所述。如果使用了多个子类,则无法保留项目的特定子类。一个模型只能有一个原型,用于 Qt 内部创建的所有项目。

这意味着如果您需要区分不同的项目类型,则不应使用多个 QStandardItem 子类。相反,您应该使用单个子类并重新实现 QStandardItem.type 来区分它们:

class MyItem(QtGui.QStandardItem):
    TypeItemA = QtGui.QStandardItem.UserType
    TypeItemB = QtGui.QStandardItem.UserType + 1
    TypeItemC = QtGui.QStandardItem.UserType + 2

    def clone(self):
        return MyItem()

    def type(self):
        return self.data(QtCore.Qt.UserRole + 1000)

    def setType(self, value):
        self.setData(QtCore.Qt.UserRole + 1000, value)

...

itemA = MyItem(self)
itemA.setType(MyItem.TypeItemA)
itemB = MyItem(self)
itemB.setType(MyItem.TypeItemB)