dropEvent() 没有被调用

2 投票
2 回答
3030 浏览
提问于 2025-04-16 06:56

我正在尝试从 QTreeWidget 拖动并放置到 QGraphicsView。拖动开始的函数 dragStart() 能正常工作,拖动进入事件 dragEnterEvent() 也能正常触发,但放置事件 dropEvent() 从来没有被调用。而且,直到光标进入 QGraphicsView,图像才会显示出来,这倒不是问题,只是我以为一开始拖动的时候图像就应该出现。以下是我的 startDrag 函数:

def on_list_startDrag(self, supportedActions):
    #Retreive the item that was clicked on
    currentPart = self.ui.list.currentItem()
    part = currentPart.text(0)

    drag = QtGui.QDrag(self.ui.list)
    mime = QtCore.QMimeData()
    print(part)
    #retreive that associated graphics file
    icon = QtGui.QIcon('drawings/FULL/' + part + '.svg')
    pixmap = icon.pixmap(102,122)

    selected = QtGui.QImage('drawings/FULL/' + part + '.svg')
    data = pickle.dumps(selected)

    mime.setData('application/x-item', data)
    #mime.setImageData(QtGui.QImage('drawings/FULL/' + part + '.svg'))
    drag.setMimeData(mime)
    drag.setHotSpot(QtCore.QPoint(pixmap.width()/2, pixmap.height()/2))
    drag.setPixmap(pixmap)
    drag.exec_()

这是 dragEnterEvent 的代码:

def on_workArea_dragEnterEvent(self, event):
    print(event.format())
    if (event.mimeData().hasFormat('application/x-item')):
        event.accept()
        print('accepted')
    else:
        event.ignore()

最后是 dropEvent 的代码:

def on_workArea_dropEvent(self, event):
    print('dropped')

当我开始拖动并放置操作时,光标上会出现一个带斜杠的圆圈,表示这个小部件不接受放置,但我已经设置了 QGraphicsView(工作区域)来接受放置。有人能帮我解决 drop 事件的问题吗?还有,为什么图像在光标移动到 QGraphicsView 上之前不会显示?谢谢。

2 个回答

0

我看了你的代码,感觉它看起来没问题,也能正常工作;dropEvent和pixmap都按预期运行。可能你代码里还有其他地方导致了你说的这个不想要的行为。关于dropEvent,你可能在连接信号和槽的时候遇到问题,这会导致你的代码没有被调用。我做了一个小例子,演示了如何在树视图和图形视图之间拖放,并加载和展示一个pixmap:

import sys
from PyQt4 import QtGui, QtCore

class TestTreeView(QtGui.QTreeView):
    def __init__(self, parent = None):
        super(TestTreeView, self).__init__(parent)
        self.setDragEnabled(True)

    def startDrag(self, dropAction):
        print('tree start drag')

        icon = QtGui.QIcon('/home/image.png')
        pixmap = icon.pixmap(64, 64)

        mime = QtCore.QMimeData()
        mime.setData('application/x-item', '???')

        drag = QtGui.QDrag(self)
        drag.setMimeData(mime)        
        drag.setHotSpot(QtCore.QPoint(pixmap.width()/2, pixmap.height()/2))
        drag.setPixmap(pixmap)        
        drag.start(QtCore.Qt.CopyAction)

class TestGraphicsView(QtGui.QGraphicsView): 
    def __init__(self, parent = None):
        super(TestGraphicsView, self).__init__(parent)
        self.setAcceptDrops(True)

    def dragEnterEvent(self, event):
        print('graphics view drag enter')
        if (event.mimeData().hasFormat('application/x-item')):
            event.acceptProposedAction()
            print('accepted')
        else:
            event.ignore()    

    def dropEvent(self, event): 
        print('graphics view drop')
        event.acceptProposedAction()                 

class MainForm(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MainForm, self).__init__(parent)

        self.model = QtGui.QStandardItemModel()

        for k in range(0, 4):
            parentItem = self.model.invisibleRootItem()
            for i in range(0, 4):
                item = QtGui.QStandardItem(QtCore.QString("item %0 %1").arg(k).arg(i))
                parentItem.appendRow(item)
                parentItem = item

        self.setMinimumSize(300, 400)

        self.view = TestTreeView(self)
        self.view.setModel(self.model)
        self.view.setMinimumSize(300, 200)

        self.graphicsView = TestGraphicsView(self)
        self.graphicsView.setGeometry(0, 210, 300, 400)        

        self.layout = QtGui.QVBoxLayout(self.centralWidget())        
        self.layout.addWidget(self.view)
        self.layout.addWidget(self.graphicsView)

def main():
    app = QtGui.QApplication(sys.argv)
    form = MainForm()
    form.show()
    app.exec_()

if __name__ == '__main__':
    main() 

希望这能帮到你,祝好

6

你需要实现 dragMoveEvent() 这个函数,否则 dropEvent() 就不会被调用。这样做的好处是,它可以让你看到正确的放置图标,而不是那个带斜杠的圆圈“不能放这里”的图标。

撰写回答