注意:我正在使用PyQt5。
我第一次在我的应用程序中“拖动”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'
我已经构建了一个小型独立演示应用程序,它在QMainWindow
内部生成QLineEdit
小部件。对于该小部件,我已覆盖所有相关功能以启用拖动(mousePressEvent(..)
,mouseMoveEvent(..)
,dragEnterEvent(..)
,...)。
请复制粘贴以下代码以查看演示:
演示代码:
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_())
''''''
请运行演示代码。当窗口出现时,单击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)
如您所见,我没有简单的方法来检测出口点。
请帮助: - )
答案 0 :(得分:1)
获得该职位的一种方法是使用QCursor::pos()
返回全局位置,并使用mapFromGlobal()
将其转换为相对于窗口小部件的位置:
def dragLeaveEvent(self, event):
event.accept()
print("Drag left at: " + str(self.mapFromGlobal(QCursor.pos())))