Как получить точку выхода из QDragLeaveEvent? - PullRequest
0 голосов
/ 25 апреля 2018

Примечание: Я работаю с PyQt5.


1.Проблема

Я впервые экспериментирую с "перетаскиванием" QWidgets в моем приложении.Я узнал, как получить точку входа перетаскивания, переопределив dragEnterEvent в соответствующем виджете:

    # Override
    def dragEnterEvent(self, event):
        if event.mimeData().hasFormat("text/plain"):
            event.acceptProposedAction()
            print("Drag entered at: " + str(event.pos()))

К сожалению, этого нельзя сделать для dragLeaveEvent.При попытке получить следующую ошибку:

AttributeError: QDragLeaveEvent объект не имеет атрибута 'pos'


2.Демонстрационное приложение

Я создал крошечное автономное демонстрационное приложение, которое порождает QMainWindow с QLineEdit -виджетом внутри.Для этого виджета я переопределил все соответствующие функции для включения перетаскивания (mousePressEvent(..), mouseMoveEvent(..), dragEnterEvent(..), ...).Пожалуйста, скопируйте и вставьте код ниже, чтобы увидеть демо:

enter image description here


Демо-код:

import sys
import os
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *


'''================================================================================'''
'''|                           CUSTOM QLINE-EDIT                                  |'''
'''================================================================================'''
class CustomLineEdit(QLineEdit):
    def __init__(self, *args, **kwargs):
        super(CustomLineEdit, self).__init__(*args, **kwargs)
        self.setReadOnly(True)
        self.setContextMenuPolicy(Qt.NoContextMenu)
        self.setMouseTracking(True)
        self.setCursorPosition(0)
        self.dragStartPosition = 0
        self.setAcceptDrops(True)
        self.setFixedHeight(50)
        self.setFixedWidth(300)

    ''''''

    def mousePressEvent(self, event):
        super(CustomLineEdit, self).mousePressEvent(event)
        if (event.button() == Qt.RightButton) or (event.modifiers() & Qt.ControlModifier):
            return
        else:
            self.dragStartPosition = event.pos()
        ###

    ''''''

    def mouseMoveEvent(self, event):
        event.accept()
        if event.buttons() == Qt.NoButton:
            return
        if (event.pos() - self.dragStartPosition).manhattanLength() < QApplication.startDragDistance():
            return

        # Start dragging
        # ---------------
        drag = QDrag(self)
        drag.setPixmap(QPixmap("cmd.png"))
        mimeData = QMimeData()
        mimeData.setText("my mime data")
        drag.setMimeData(mimeData)
        dropAction = drag.exec(Qt.CopyAction | Qt.MoveAction)

    ''''''

    def dragEnterEvent(self, event):
        if event.mimeData().hasFormat("text/plain"):
            event.acceptProposedAction()
            print("Drag entered at: " + str(event.pos()))
        ###

    ''''''

    def dragLeaveEvent(self, event):
        event.accept()
        # print("Drag left at: " + str(event.pos()))  # <- doesn't work :-(
        print("Drag left at: ?")

    ''''''

    def dropEvent(self, event):
        if event.mimeData().hasFormat("text/plain"):
            event.acceptProposedAction()
            print("Drag dropped at: " + str(event.pos()))
        ###

    ''''''


'''================================================================================'''
'''|                           CUSTOM MAIN WINDOW                                 |'''
'''================================================================================'''
class CustomMainWindow(QMainWindow):

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

        # -------------------------------- #
        #           Window setup           #
        # -------------------------------- #

        # 1. Define the geometry of the main window
        # ------------------------------------------
        self.setGeometry(100, 100, 800, 200)
        self.setWindowTitle("QLineEdit test")

        # 2. Create frame and layout
        # ---------------------------
        self.__frm = QFrame(self)
        self.__frm.setStyleSheet("QWidget { background-color: #ffffff }")
        self.__lyt = QVBoxLayout()
        self.__lyt.setAlignment(Qt.AlignTop)
        self.__frm.setLayout(self.__lyt)
        self.setCentralWidget(self.__frm)

        # 3. Create QLineEdit
        # -------------------
        self.__myQLineEdit = CustomLineEdit()
        self.__lyt.addWidget(self.__myQLineEdit)


        self.show()

'''=== end Class ==='''


if __name__ == '__main__':
    app = QApplication(sys.argv)
    QApplication.setStyle(QStyleFactory.create('Fusion'))
    myGUI = CustomMainWindow()
    sys.exit(app.exec_())

''''''


3.Вывод демонстрационного приложения

Пожалуйста, запустите демонстрационный код.Когда появится окно, щелкните где-нибудь в виджете QLineEdit и переместите указатель мыши внутрь и наружу.Вы должны получить такой вывод в консоли / терминале:

Drag entered at: PyQt5.QtCore.QPoint(100, 22)
Drag left at: ?
Drag entered at: PyQt5.QtCore.QPoint(132, 49)
Drag left at: ?
Drag entered at: PyQt5.QtCore.QPoint(229, 49)
Drag left at: ?
Drag entered at: PyQt5.QtCore.QPoint(242, 49)
Drag dropped at: PyQt5.QtCore.QPoint(230, 23)

Как видите, у меня нет простого способа определить точки выхода.

Пожалуйста, помогите: -)

1 Ответ

0 голосов
/ 25 апреля 2018

Один из способов получить позицию - использовать QCursor::pos(), которая возвращает глобальную позицию, и преобразовать ее в позицию относительно виджета, используя mapFromGlobal():

def dragLeaveEvent(self, event):
    event.accept()
    print("Drag left at: " + str(self.mapFromGlobal(QCursor.pos())))
...