= Handling Qt's internal item MIME type = Normally, to perform drag and drop between two item views, the developer would create their own model, reimplementing the `mimeData()` method to return a custom MIME type and the `dropMimeData()` method to accept data with this MIME type. However, this seems like a lot of work, especially when the data comes from a standard model. The following code implements a model that you can use for the view that accepts dropped data. The `decode_data()` method decodes `application/x-qabstractitemmodeldatalist` MIME type data supplied by a standard model. The reimplementation of the `dropMimeData()` method takes the decoded data and either adds a new item to the top level of a tree structure or increments a counter associated with each item. Qt's item views pass around items using the internal `application/x-qabstractitemmodeldatalist` MIME type (see the [[http://doc.trolltech.com/4.5/model-view-model-subclassing.html#mime-data|Model Subclassing Reference]] for more information about this type). For practical purposes, it may be useful to be able to unpack data sent in this format when implementing a drop handler for a custom model. The example shown in this document shows how this can be done in Python. {{{ #!python import sys from PyQt4.QtCore import QDataStream, Qt, QVariant from PyQt4.QtGui import * class TreeModel(QStandardItemModel): def __init__(self, parent = None): QStandardItemModel.__init__(self, parent) }}} The start of the `dropMimeData()` method queries the MIME data for the format we recognise. If it can supply data in the internal MIME type used by Qt, we call a helper method to unpack it. The helper method will return a list of dictionaries corresponding to each of the items dropped onto the view. Each dictionary maps a role number to corresponding data for that role. We are interested in the text supplied in the display role. {{{ #!python def dropMimeData(self, data, action, row, column, parent): if data.hasFormat('application/x-qabstractitemmodeldatalist'): bytearray = data.data('application/x-qabstractitemmodeldatalist') data_items = self.decode_data(bytearray) # Assuming that we get at least one item, and that it defines # text that we can display. text = data_items[0][Qt.DisplayRole].toString() for row in range(self.rowCount()): name = self.item(row, 0).text() if name == text: number_item = self.item(row, 1) number = int(number_item.text()) number_item.setText(str(number + 1)) break else: name_item = QStandardItem(text) number_item = QStandardItem("1") self.appendRow([name_item, number_item]) return True else: return QStandardItemModel.dropMimeData(self, data, action, row, column, parent) }}} The rest of this method just does what the requester wanted: it puts the names into the model with an associated number, starting at 1, or increments the number associated with existing items if they are already present in the model. Data not handled by us is passed to the base class's implementation of `dropMimeData()`. The `decode_data()` method relies on the internal format used by Qt when sending items as MIME data. The byte array is opened using a data stream and unpacked using the information that it contains a sequence of items, each stored as a pair of row and column integers followed by a map of role integers to `QVariant` values. (See [[http://doc.trolltech.com/4.5/datastreamformat.html|Format of the QDataStream Operators]] for more information about how these are serialised by Qt.) {{{ #!python def decode_data(self, bytearray): data = [] item = {} ds = QDataStream(bytearray) while not ds.atEnd(): row = ds.readInt32() column = ds.readInt32() map_items = ds.readInt32() for i in range(map_items): key = ds.readInt32() value = QVariant() ds >> value item[Qt.ItemDataRole(key)] = value data.append(item) return data app = QApplication(sys.argv) window = QWidget() listModel = QStringListModel(["John", "Jane", "Frank", "Henry"]) listView = QListView() listView.setModel(listModel) listView.setDragEnabled(True) treeModel = TreeModel() treeView = QTreeView() treeView.setHeaderHidden(True) treeView.setRootIsDecorated(False) treeView.setAcceptDrops(True) treeView.setModel(treeModel) layout = QHBoxLayout(window) layout.addWidget(listView) layout.addWidget(treeView) window.show() sys.exit(app.exec_()) }}}