如何从QDragLeaveEvent获取退出点?

时间:2018-04-25 12:31:53

标签: python qt pyqt qt5 pyqt5

注意:我正在使用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-widget中的某个位置并移动鼠标。您应该在控制台/终端中获得这样的输出:

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 :(得分:1)

获得该职位的一种方法是使用QCursor::pos()返回全局位置,并使用mapFromGlobal()将其转换为相对于窗口小部件的位置:

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