QListView - 如何将 QApplication 外部的拖动添加到默认行为
QListView - how to add drag outside QApplication to default behaviour
我正在尝试修改一个 QListView/QStandardItemModel 组合,这样我就可以将一个项目拖到 QApplication 之外,然后将其放入带有自定义数据的电子邮件客户端中。不过,我也想保留默认的拖放行为,这样我就可以在视图之间拖放项目。
我曾希望从那里重新实现模型的 dropMimeData(), but whilst I can access the default mimeData this way, executing my own drag QDrag 实例使 QT 崩溃。
覆盖视图的 mouseMoveEvent() like in this tutorial 将使我能够将项目拖到应用程序之外,但它会覆盖默认行为。
理想情况下,我只想将纯文本添加到默认的 mimeData(如下面的错误示例中所示),或者我很乐意知道如何从头开始编写自己的拖动行为,以便它同时工作在应用程序内部(即在视图之间复制项目)以及在应用程序外部(例如将文本放入电子邮件中)。
这是我的测试代码:
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_()
发布后一分钟我突然意识到:
我只需要重新实现模型的 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_()
我正在尝试修改一个 QListView/QStandardItemModel 组合,这样我就可以将一个项目拖到 QApplication 之外,然后将其放入带有自定义数据的电子邮件客户端中。不过,我也想保留默认的拖放行为,这样我就可以在视图之间拖放项目。
我曾希望从那里重新实现模型的 dropMimeData(), but whilst I can access the default mimeData this way, executing my own drag QDrag 实例使 QT 崩溃。
覆盖视图的 mouseMoveEvent() like in this tutorial 将使我能够将项目拖到应用程序之外,但它会覆盖默认行为。
理想情况下,我只想将纯文本添加到默认的 mimeData(如下面的错误示例中所示),或者我很乐意知道如何从头开始编写自己的拖动行为,以便它同时工作在应用程序内部(即在视图之间复制项目)以及在应用程序外部(例如将文本放入电子邮件中)。
这是我的测试代码:
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_()
发布后一分钟我突然意识到: 我只需要重新实现模型的 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_()