过早结束QDrag

时间:2016-02-19 23:10:40

标签: qt pyqt qt5 pyqt5

我希望我的应用程序终止dragLeaveEvent中的所有拖放操作,而无需用户释放鼠标按钮。

问题是循环暂停所有可能在QDrag发生时取消的事件,即使文档声明:

  

“在Linux和Mac OS X上,拖放操作可能会占用一些   时间,但此功能不会阻止事件循环。其他事件   在操作时仍然会将其交付给应用程序   执行。在Windows上,Qt事件循环在期间被阻止   操作。但是,Windows上的QDrag.exec()会导致processEvents()   经常调用以保持GUI响应。如果有任何循环或   在拖动操作处于活动状态时调用操作,它将阻塞   拖动操作。“

因此,我无法调用会结束阻力的事件。

到目前为止,我已尝试过建议here,如代码所示。我正在使用PyQt5,但如果解决方案在Qt中有效,它应该在PyQt中工作。

编辑:我有点害怕删除拖动,因为场景不拥有它。我想我可以把它设置为拥有它,但是发布时here它应该不起作用。

Edit2:添加了我的非工作尝试来修复它的代码。我真的很想解决这个问题,而不必自己制作拖放框架。还修剪了帖子。

import sys
from PyQt5.QtWidgets import (QMainWindow, QApplication,
    QGraphicsView, QGraphicsScene, QGraphicsWidget, QGraphicsRectItem)
from PyQt5.QtCore import (QMimeData, Qt, QByteArray, QCoreApplication,
    QEvent, QPoint)
from PyQt5.QtGui import QBrush, QColor, QDrag, QPen, QMouseEvent


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.scene = CustomScene()
        self.view = QGraphicsView(self.scene, self)
        self.setGeometry(100, 100, 600, 600)
        self.view.setGeometry(0, 0, 500, 500)
        self.show()


class CustomScene(QGraphicsScene):
    def __init__(self):
        super().__init__()
        self.customWidgets = []
        for i in range(5):
            newItem = CustomDragWidget()
            self.addItem(newItem)
            self.customWidgets.append(newItem)
            newItem.setGeometry(i * 50, i * 50, 50, 50)

    def dragLeaveEvent(self, event):
        # Work your magic here. I've tried the following:
        # 1)
        self.customWidgets[0].dropEvent(event)
        # 2)
        self.dropEvent(event)
        # 3)
        eve = QMouseEvent(QEvent.MouseButtonRelease, QPoint(0, 0), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier)
        QCoreApplication.sendEvent(self.views()[0], eve)
        QCoreApplication.processEvents()
        # 4)
        eve = QMouseEvent(QEvent.MouseButtonRelease, QPoint(0, 0), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier)
        QCoreApplication.sendEvent(self.customWidgets[0], eve)
        QCoreApplication.processEvents()

    def dropEvent(self, QGraphicsSceneDragDropEvent):
        # a dummy dropevent that tries to stop the drop, but doesnt work
        QGraphicsSceneDragDropEvent.accept()

class CustomDragWidget(QGraphicsWidget):
    def __init__(self,):
        super().__init__()
        self.squareItem = QGraphicsRectItem()
        self.squareItem.setBrush(QBrush(QColor(Qt.blue)))
        self.squareItem.setPen(QPen(QColor(Qt.black), 2))
        self.squareItem.setRect(0, 0, 50, 50)
        self.squareItem.setParentItem(self)
        self.setAcceptDrops(True)

    def mousePressEvent(self, event):
        mime = QMimeData()
        itemData = QByteArray()
        mime.setData('application/x-dnditemdata', itemData)
        drag = QDrag(self)
        drag.setMimeData(mime)
        drag.exec(Qt.MoveAction)

    def dropEvent(self, event):
        event.accept()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
    sys.exit(app.exec_())

1 个答案:

答案 0 :(得分:1)

这有点像hackish,但似乎有效(无论如何在Linux上):

    def dragLeaveEvent(self, event):
        QCoreApplication.postEvent(self,
            QKeyEvent(QEvent.KeyPress, Qt.Key_Escape, Qt.NoModifier))