Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Qt 过早结束QDrag_Qt_Pyqt_Qt5_Pyqt5 - Fatal编程技术网

Qt 过早结束QDrag

Qt 过早结束QDrag,qt,pyqt,qt5,pyqt5,Qt,Pyqt,Qt5,Pyqt5,我希望我的应用程序在dragleavevent中终止所有拖放操作,而无需用户释放鼠标按钮 问题在于,循环会在发生时暂停所有可能取消QDrag的事件,即使文档中指出: “在Linux和Mac OS X上,拖放操作可能需要一些时间 时间,但此函数不阻止事件循环。其他事件 在执行操作时,仍会传递到应用程序 已执行。在Windows上,Qt事件循环在 但是,Windows上的QDrag.exec()会导致processEvents()失败 频繁调用以保持GUI响应。如果有任何循环或 当拖动操作处于活动状

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

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

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

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

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

编辑:我有点害怕删除拖动,因为场景并不拥有它。我想我可以把它设置为自己的,但正如张贴的那样,它不应该工作

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

这有点黑客化,但似乎是可行的(无论如何,在Linux上):


你能提供一个小的,独立的例子来说明这个问题吗?当然!我正在编辑这篇文章。编辑完成了,代码现在可以复制了。在Windows10世界里,它不起作用。禁止光标仍在显示:(@TheSmartWon。按真正的escape键是否会取消Windows上的拖动?或者是否有其他方法可以通过Windows上的键盘取消拖动?escape键确实会取消Windows上的word。似乎无论在何处收到该事件,该事件仍然没有进入QDrop的链接。也许这只是Windows的问题。@TheSmartWon。是的,我的直觉是,你基本上被Windows搞砸了。它只是阻止了一切。似乎Qt在Windows上使用平台拖放系统,所以没有办法中断。也许你可以使用WinAPI来解决这个问题,但我不知道如何解决。听起来不错。谢谢你的帮助,我将编写自己的拖放系统与其他老鼠事件不同。通常这种疼痛不值得。
    def dragLeaveEvent(self, event):
        QCoreApplication.postEvent(self,
            QKeyEvent(QEvent.KeyPress, Qt.Key_Escape, Qt.NoModifier))