You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 08:44:31