I am writing a PySide application with a QListView
. This QListView
allows drag and drop events to change the order of the items it displays.
The QListView
uses a QStandardItemModel
, and the QStandardItemModel
contains QStanardItem
objects. I have given these QStandardItem
objects custom instance attributes, as follows:
def createShotItem(self, path, display_name, name):
item = CustomItem(display_name)
item.setCheckable(True)
item.setCheckState(QtCore.Qt.Checked)
item.path = path
item.name = name
item.fields = {} # Used to store setting fields
return item
Below is the CustomItem
class.
class CustomItem(QtGui.QStandardItem):
def __init__(self, text):
self.shot_path = ""
self.name = ""
self.fields = {}
super(CustomItem, self).__init__(text)
Previously, I was simply adding the attributes directly to a QStandardItem
, without using a sub-class. There was no difference.
The sub-classed QListView
and QStandardItemModel
classes are as follows:
class DragDropListView(QtGui.QListView):
def __init__(self):
super(DragDropListView, self).__init__()
self.setAcceptDrops(True)
self.setDragDropMode(QtGui.QAbstractItemView.DragDrop)
self.setDefaultDropAction(QtCore.Qt.MoveAction)
self.setDragDropOverwriteMode(False)
self.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
def dragEnterEvent(self, event):
if __name__ == '__main__':
if event.mimeData().hasUrls:
event.acceptProposedAction()
else:
super(DragDropListView, self).dragEnterEvent(event)
class DragDropItemModel(QtGui.QStandardItemModel):
def __init__(self):
super(DragDropItemModel, self).__init__()
def flags(self, index):
if index.isValid():
return QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsDragEnabled | QtCore.Qt.ItemIsEnabled \
| QtCore.Qt.ItemIsUserCheckable
return QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsDragEnabled \
| QtCore.Qt.ItemIsDropEnabled | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsUserCheckable
When I later attempt to access one of these attributes on an item who has been moved in the list, I get an error as follows:
AttributeError: 'PySide.QtGui.QStandardItem' object has no attribute 'fields'
As you can see, my CustomItem
, which extends QStandardItem
, has been replaced by a QStandardItem
that does not contain any of my custom attributes.
I believe that this is because, when a re-order occurs, due to a drag-and-drop event, PySide creates a new QStandardItem
at the desired index, containing the same text
attribute, and other PySide attributes, but discarding my custom attributes.
Note that accessing these custom attributes works fine on all unmoved items. Also, appending or inserting a CustomItem
using model.appendRow(item)
or model.insertRow(index, item)
works fine, so the issue is not with those methods.
How can I maintain these custom attributes throughout move events? Do I need to alter the behavior of the move event, and if so, how?