Dariusz
Dariusz

Reputation: 1044

Preserve QStandardItem subclasses in drag and drop

I have:

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)

When I move itemB to itemA and check its class, ItemB is no longer a SubclassQStandardItemB but a QStandardItem.

How can I keep the original class of the item when I drag and drop?

Upvotes: 1

Views: 1385

Answers (1)

ekhumoro
ekhumoro

Reputation: 120578

As explained in this answer, 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. There is no way to preserve the specific subclass of the item if there are multiple subclasses being used. A model can have only one prototype, and that is used for all items that are created internally by Qt.

This means you should not use multiple QStandardItem subclasses if you need to distinguish between different item types. Instead, you should use a single subclass and reimplement QStandardItem.type to distinguish between them:

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)

Upvotes: 1

Related Questions