QListView - 如何将 QApplication 外部的拖动添加到默认行为

Posted

技术标签:

【中文标题】QListView - 如何将 QApplication 外部的拖动添加到默认行为【英文标题】:QListView - how to add drag outside QApplication to default behaviour 【发布时间】:2018-08-05 02:23:57 【问题描述】:

我正在尝试修改 QListView/QStandardItemModel 组合,以便我可以将一个项目拖到 QApplication 之外,然后将其放入我的电子邮件客户端,例如我的自定义数据。我也想保留默认的拖放行为,所以我可以在视图之间拖放项目。

我曾希望只是重新实现模型的 dropMimeData(),但是虽然我可以通过这种方式访问​​默认的 mimeData,但从那里执行我自己的拖动 QDrag 实例会使 QT 崩溃。

在this tutorial 中覆盖视图的mouseMoveEvent() 将使我能够将项目拖到应用程序之外,但它会覆盖默认行为。

理想情况下,我只想将纯文本添加到默认的 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_()

【问题讨论】:

【参考方案1】:

发布后一分钟我突然意识到: 我只需要重新实现模型的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 - 如何将 QApplication 外部的拖动添加到默认行为的主要内容,如果未能解决你的问题,请参考以下文章

QListView - 如何将 QApplication 外部的拖动添加到默认行为

如何将 QModelIndex 设置为 QListView

如何在 QListView 中修改 drop 事件

如何从 QT 中的 QListView 获取所选项目的文本? [复制]

如何防止 Qt 对 QListView 中的图标进行 alpha 混合选择?

PyQt4 - 在 QListView 中的项目上按下 Enter 键