Как в pyqt5 программно запустить перетаскивание виджета при отжатой мыши?

Возникла необходимость программного запуска перетаскивания drag, перемещаю кнопки с qtoolbox на qgraphicview. При дропе создаю на полотне сцены graphicitem. На текущий момент повесил shortcut на запуск drag.exec(), но после нажатия сочетания клавиш, оно дропается на месте указателя мыши. Желаемое поведение, чтобы оно запустило процесс перетаскивания и следовало за мышью без зажатой левой кнопки мыши и чтобы была возможность выбора точки дропа.

обнолено: клавиша 'Q' для предпологаемого включения режима drag (по факту идет дроп на текущее местоположение мыши)

пример кода

import sys

from PyQt5.QtCore import Qt, QSize, QMimeData, QByteArray
from PyQt5.QtGui import QIcon, QDrag
from PyQt5.QtWidgets import QMainWindow, QApplication, QGraphicsScene, QGraphicsView, QToolBox, QGridLayout, \
    QToolButton, QButtonGroup, QLabel, QWidget, QAction, QSizePolicy, QHBoxLayout, QGraphicsRectItem, QGraphicsItem, \
    QStyle


class MyGraphicsView(QGraphicsView):
    def dragEnterEvent(self, event):
        if event.mimeData().hasFormat("item/rect"):
            event.acceptProposedAction()
            self.update()

    def dragMoveEvent(self, event):
        if event.mimeData().hasFormat("item/rect"):
            event.acceptProposedAction()

    def dropEvent(self, event):
        if event.mimeData().hasFormat("item/rect"):
            pos = self.mapToScene(event.pos())
            item = QGraphicsRectItem(0, 0, 300, 300)
            item.setFlag(QGraphicsItem.ItemIsMovable)
            self.scene().addItem(item)
            item.setPos(pos)
            self.update()

class MainWindow(QMainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()

        self.scene = QGraphicsScene(-300, -300, 2520, 1680)
        self.view = MyGraphicsView(self.scene)
        self.view.centerOn(self.view.viewport().rect().topLeft())
        self.view.viewport().update()

        self.toolBox = QToolBox()
        self.buttonGroup = QButtonGroup()

        layout = QGridLayout()
        layout.setContentsMargins(0, 0, 0, 0)

        name = "item"
        icon = QIcon(QApplication.style().standardIcon(QStyle.SP_DesktopIcon))
        button = QToolButton()
        button.setIcon(icon)
        button.setIconSize(QSize(50, 50))
        button.setCheckable(True)
        button.mouseMoveEvent = self.enableDrag
        self.buttonGroup.addButton(button)

        self.button = button

        layout = QGridLayout()
        layout.addWidget(button, 0, 0, Qt.AlignHCenter)
        layout.addWidget(QLabel(name), 1, 0, Qt.AlignCenter)

        action = QAction("startDrag", self)
        action.triggered.connect(self.enableDrag)
        action.setShortcut("Q")
        action.setStatusTip("Начать перетаскивание")
        button.addAction(action)

        layout.setRowStretch(2, 2)
        layout.setColumnStretch(1, 2)

        block = QWidget()
        block.setLayout(layout)

        self.toolBox.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred))
        self.toolBox.addItem(block, "toolbox")

        l = QHBoxLayout()
        l.addWidget(self.toolBox)
        l.addWidget(self.view)

        self.widget = QWidget()
        self.widget.setLayout(l)

        self.setCentralWidget(self.widget)

    def enableDrag(self, *args):
        print("pressed")
        drag = QDrag(self.button)
        mime = QMimeData()
        drag.setMimeData(mime)

        mime.setData("item/rect", QByteArray(b''))

        pixmap = self.button.icon().pixmap(QSize(64, 64))
        pixmap.setMask(pixmap.createHeuristicMask())

        drag.setPixmap(pixmap)
        drag.setHotSpot(pixmap.rect().topLeft())

        drag.exec_()

if __name__ == '__main__':
    app = QApplication(sys.argv)

    window = MainWindow()
    window.setVisible(True)

    sys.exit(app.exec_())

Ответы (0 шт):