Я хочу, чтобы мое приложение прекратило все перетаскивания и падения в dragLeaveEvent
, не отпуская кнопку мыши.Окончание QDrag Преждевременно
Проблема заключается в том, что цикл приостанавливает все события, которые могут отменить QDrag
в то время как это происходит, даже если в документации говорится:
«В Linux и Mac OS X, в операции перетаскивания может занять некоторое время , но эта функция не блокирует цикл событий. Другие события по-прежнему доставляются в приложение при выполнении операции . В Windows цикл событий Qt блокируется во время операции . Однако QDrag.exec () в Windows приводит к тому, что processEvents() до часто вызывается, чтобы поддерживать графический интерфейс. любые циклы или операции вызывают, когда активна операция перетаскивания, она будет блокировать операцию перетаскивания ». .
Из-за этого я не могу вызывать события, которые могут привести к перетаскиванию.
До сих пор я пробовал, что предлагается 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_())
Может ли вы предоставить небольшой автономный пример, демонстрирующий эту проблему? – ekhumoro
Конечно! Теперь я редактирую сообщение. – TheSmartWon
Готово к редактированию, а код теперь доступен для копирования. – TheSmartWon