如何在PyQt5的QDragLeaveEvent中获取拖拽源组件?
如何在PyQt5的QDragLeaveEvent中获取拖拽源组件?
嗨,我懂你现在遇到的困扰——QDragLeaveEvent确实不像QDragEnterEvent那样直接提供source()方法来获取拖拽源组件,这事儿确实有点让人头疼。不过别担心,咱们可以通过一个简单的“跟踪变量”技巧来解决这个问题!
思路其实很简单:在主窗口里维护一个实例变量,专门用来记录当前正在拖拽的组件。当dragEnterEvent触发时,我们把拖拽源存到这个变量里;之后不管是dropEvent还是dragLeaveEvent触发,都能直接从这个变量里拿到拖拽源的信息啦。
下面是修改后的完整代码,我标出来了关键的改动部分:
#!/usr/bin/env python3 from PyQt5.QtWidgets import (QApplication, QWidget, QMainWindow, QVBoxLayout, QPushButton, QGridLayout ) from PyQt5.QtCore import Qt, QMimeData, pyqtSignal, pyqtSlot from PyQt5.QtGui import QDrag, QPixmap, QCursor class DragWidget(QWidget): def __init__(self, *args, name , **kwargs): super().__init__(*args, **kwargs) def mouseMoveEvent(self, e): if e.buttons() == Qt.LeftButton: drag = QDrag(self) mime = QMimeData() drag.setMimeData(mime) pixmap = QPixmap(self.size()) self.render(pixmap) drag.setPixmap(pixmap) drag.exec_(Qt.MoveAction) class MainWindow(QMainWindow): whereDropped = pyqtSignal(int,int) dragleaves = pyqtSignal() def __init__(self): super().__init__() self.setGeometry(200,200, 400, 500) self.container = QWidget() self.layout = QGridLayout() self.container.setLayout(self.layout) self.setCentralWidget(self.container) # 新增:初始化跟踪拖拽源的变量 self.current_drag_source = None for i in range(4): self.x = DragWidget(self, name = 'widget_'+str(i)) self.layout.addWidget( self.x) self.x.setObjectName('widget_'+str(i)) self.b = QPushButton('widget___'+str(i)) self.layout_2 = QVBoxLayout() self.x.setLayout(self.layout_2) self.layout_2.addWidget(self.b) self.x.show() self.installEventFilter(self) self.setAcceptDrops(True) self.whereDropped.connect(self.attdeta) self.dragleaves.connect(self.removeParent) @pyqtSlot() def removeParent(self) : print("\n\nself.dragleaves.connect(self.removeParent))") pass @pyqtSlot(int, int) def attdeta(self, tupx, tupy) : print("\n\nself.whereDropped.connect(self.attdeta)") print('tupxy : ', tupx , tupy) def dropEvent(self, e): pos = e.pos() widget = e.source() print('\n\ndropEvent _________') print('widget = e.source() :' , widget) print('e.pos() : ' , pos ,'\n\n') self.whereDropped.emit(e.pos().x(), e.pos().y()) # 新增:拖拽完成后清空跟踪变量 self.current_drag_source = None e.accept() def dragEnterEvent(self, e): print('dragEnterEvent _________' , e.source(), '\n') print('dragEnterEvent _________event-source-name :' ,e.source().objectName()) print('e.pos() : ' , e.pos().x()) print('e.pos() : ' , e.pos().y() ,'\n\n') # 新增:记录当前拖拽源 self.current_drag_source = e.source() e.accept() def dragLeaveEvent(self, event): print('\n\nDragLeaveEvent event : ', event) # 现在可以直接用self.current_drag_source获取拖拽源了! if self.current_drag_source: print('拖拽源组件:', self.current_drag_source) print('拖拽源名称:', self.current_drag_source.objectName()) print("Drag left at: " + str(self.mapFromGlobal(QCursor.pos()))) print('self.dragleaves.emit()') self.whereDropped.emit(self.mapFromGlobal(QCursor.pos()).x(), self.mapFromGlobal(QCursor.pos()).y()) self.dragleaves.emit() # 新增:拖拽离开后清空跟踪变量 self.current_drag_source = None event.accept() app = QApplication([]) w = MainWindow() w.show() app.exec_()
你看,这样修改之后,在dragLeaveEvent里就能通过self.current_drag_source轻松拿到拖拽源组件的信息了。另外要注意在dropEvent和dragLeaveEvent最后清空这个变量,避免下次拖拽时残留旧的数据哦。
备注:内容来源于stack exchange,提问作者pippo1980
相关产品推荐
相关产品推荐

