过早结束 QDrag



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

问题在于,循环会在QDrag发生时挂起所有可能取消的事件,即使文档指出:

"在Linux和Mac OS X上,拖放操作可能需要一些时间。 时间,但此函数不会阻塞事件循环。其他活动 在操作时仍会传递到应用程序 执行。在 Windows 上,Qt 事件循环在 操作。但是,Windows 上的 QDrag.exec() 会导致 processEvents() 频繁调用以保持 GUI 响应。如果有任何循环或 拖动操作处于活动状态时调用操作,它将阻止 拖拽操作。

因此,我无法调用将结束拖累的事件。

到目前为止,我已经尝试了此处建议的内容,如代码所示。我正在使用 PyQt5,但如果解决方案在 Qt 中工作,它应该在 PyQt 中工作。

编辑:我有点害怕删除拖拽,因为场景不拥有它。我想我可以设置它来拥有它,但正如这里发布的那样,它应该不起作用。

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

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_())

这有点黑客,但它似乎可以工作(无论如何,在 Linux 上):

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

相关内容

  • 没有找到相关文章

最新更新