Issue
I am trying to modify a QListView/QStandardItemModel combo so that I can drag an item outside of the QApplication and drop it in, say, my email client with custom data. I also want to keep the default drag&drop behaviour though, so I can drag&drop items between views.
I had hoped to just re-implement the model's dropMimeData(), but whilst I can access the default mimeData this way, executing my own drag QDrag instance from there crashes QT.
Overwriting the view's mouseMoveEvent() like in this tutorial will enable me to drag an item outside the application, but it overwrites the default behaviour.
Ideally I'd like to just add plain text to the default mimeData (like in the faulty example below), alternatively I'd be happy to know how to write my own drag behaviour from scratch so that it works both inside the application (i.e. to copy items between views) as well as outside the application (e.g. to drop text into an email).
Here is my test code:
import sys
from PySide import QtGui, QtCore
class MyModel(QtGui.QStandardItemModel):
def __init__(self, w, parent=None):
super(MyModel, self).__init__(parent)
def dropMimeData(self, data, action, row, column, parent):
super(MyModel, self).dropMimeData(data, action, row, column, parent)
# this crashes
data.setText('test')
drag = QtGui.QDrag(None) # it crashes even if I supply a parent widget
drag.setMimeData(data)
drag.exec_()
###############
return True
class MyList(QtGui.QListView):
def __init__(self, parent=None):
super(MyList, self).__init__(parent)
self.setDragEnabled(True)
self.setAcceptDrops(True)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
list1 = MyList()
list2 = MyList()
model1 = MyModel(list1)
model2 = MyModel(list1)
model2.setItemPrototype(QtGui.QStandardItem())
foods = [
'Cookie dough',
'Hummus',
'Spaghetti',
'Dal makhani',
'Chocolate whipped cream'
]
for food in foods:
item = QtGui.QStandardItem(food)
model1.appendRow(item)
list1.setModel(model1)
list2.setModel(model2)
w = QtGui.QSplitter()
w.addWidget(list1)
w.addWidget(list2)
w.show()
w.raise_()
app.exec_()
Solution
One minute after posting it dawned on me: I simply need to re-implement the model's mimeData():
import sys
from PySide import QtGui, QtCore
class MyModel(QtGui.QStandardItemModel):
def __init__(self, w, parent=None):
super(MyModel, self).__init__(parent)
def mimeData(self, indexes):
mimeData = super(MyModel, self).mimeData(indexes)
mimeData.setText('test')
return mimeData
class MyList(QtGui.QListView):
def __init__(self, parent=None):
super(MyList, self).__init__(parent)
self.setDragEnabled(True)
self.setAcceptDrops(True)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
list1 = MyList()
list2 = MyList()
model1 = MyModel(list1)
model2 = MyModel(list1)
model2.setItemPrototype(QtGui.QStandardItem())
foods = [
'Cookie dough',
'Hummus',
'Spaghetti',
'Dal makhani',
'Chocolate whipped cream'
]
for food in foods:
item = QtGui.QStandardItem(food)
model1.appendRow(item)
list1.setModel(model1)
list2.setModel(model2)
w = QtGui.QSplitter()
w.addWidget(list1)
w.addWidget(list2)
w.show()
w.raise_()
app.exec_()
Answered By - Frank Rueter
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.