dropEvent 不在 PyQt5 中触发
dropEvent not firing in PyQt5
我正在尝试在我的应用程序中实现拖放,但从未调用目标小部件中的 dropEvent
。
我搜索了很多这个问题,但我找到的每个解决方案都涉及覆盖 dragMoveEvent
,我也这样做了,但没有区别。
由于上述原因,这个示例代码对我来说也不起作用:
主要windowclass:
class Win(QtWidgets.QWidget):
def __init__(self):
super(Win, self).__init__()
self.setGeometry(200, 300, 400, 200)
self.setLayout(QtWidgets.QHBoxLayout())
self.layout().addWidget(DragLabel())
self.layout().addWidget(DropTest())
要拖动的标签:
class DragLabel(QtWidgets.QLabel):
def __init__(self):
super(DragLabel, self).__init__()
self.setText("Drag me")
def mouseMoveEvent(self, e):
if e.buttons() != QtCore.Qt.LeftButton:
return
mimeData = QtCore.QMimeData()
mimeData.setText("Test drop")
drag = QtGui.QDrag(self)
drag.setMimeData(mimeData)
dropAction = drag.exec(QtCore.Qt.CopyAction)
要放置到的小部件:
class DropTest(QtWidgets.QWidget):
def __init__(self):
super(DropTest, self).__init__()
self.setAcceptDrops(True)
def dragEnterEvent(self, e):
print("DragEnter")
e.accept()
def dragMoveEvent(self, e):
print("DragMove")
e.accept()
def dropEvent(self, e):
print("DropEvent")
position = e.pos()
print(position)
e.accept()
当我将标签拖到另一个小部件上时,我看到 dragEnterEvent
和 dragMoveEvent
都被调用了,但是当我实际放下标签时,我没有从 dropEvent
函数。
此外,关闭 window 应用程序后将挂起并且不会退出。
我正在使用 PyQt 5.13.1 x86_64 在 Fedora 31 中安装了 DNF。Python 版本是 3.7.5,没有 virtualenv。
试一试:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class DropTest(QtWidgets.QLabel): # - QWidget + QLabel
def __init__(self):
super(DropTest, self).__init__()
self.setAcceptDrops(True)
self.setText(" Accept Drops")
self.setStyleSheet("QLabel { background-color : #ccd; color : blue; font-size: 20px;}")
def dragEnterEvent(self, e):
# print("DragEnter")
e.accept()
def dragMoveEvent(self, e):
# print("DragMove")
e.accept()
def dropEvent(self, e):
# print("DropEvent")
# position = e.pos()
# print(position)
self.setText(e.mimeData().text()) # +++
e.setDropAction(Qt.MoveAction) # +++
e.accept()
class DragLabel(QtWidgets.QLabel):
def __init__(self):
super(DragLabel, self).__init__()
self.setText("Drag me")
def mouseMoveEvent(self, e):
if e.buttons() != QtCore.Qt.LeftButton:
return
mimeData = QtCore.QMimeData()
mimeData.setText(self.text()) # ("Test drop")
drag = QtGui.QDrag(self)
drag.setMimeData(mimeData)
dropAction = drag.exec(QtCore.Qt.CopyAction)
class Win(QtWidgets.QWidget):
def __init__(self):
super(Win, self).__init__()
self.setGeometry(200, 300, 400, 200)
self.setLayout(QtWidgets.QHBoxLayout())
self.layout().addWidget(DragLabel())
self.layout().addWidget(DropTest())
if __name__ == '__main__':
app = QApplication(sys.argv)
w = Win()
w.show()
sys.exit(app.exec_())
如评论中所述,我已经在 , and I have tested it in a docker with fedora31 and it works correctly so after a discussion with the OP he pointed out it in a :
中回答了相同的问题
[PyQt5] was previously installed from
DNF, but I'm pretty sure setuptools also installed it from pip as a
dependency of my application.
问题的原因是OP结合了两种安装方式:dnf和pip,它们分别使用不同版本的Qt、编译标志等进行编译,这可能会导致某些功能失败。解决方法是两种方法都卸载PyQt5,只重装其中一种。
我正在尝试在我的应用程序中实现拖放,但从未调用目标小部件中的 dropEvent
。
我搜索了很多这个问题,但我找到的每个解决方案都涉及覆盖 dragMoveEvent
,我也这样做了,但没有区别。
由于上述原因,这个示例代码对我来说也不起作用:
主要windowclass:
class Win(QtWidgets.QWidget):
def __init__(self):
super(Win, self).__init__()
self.setGeometry(200, 300, 400, 200)
self.setLayout(QtWidgets.QHBoxLayout())
self.layout().addWidget(DragLabel())
self.layout().addWidget(DropTest())
要拖动的标签:
class DragLabel(QtWidgets.QLabel):
def __init__(self):
super(DragLabel, self).__init__()
self.setText("Drag me")
def mouseMoveEvent(self, e):
if e.buttons() != QtCore.Qt.LeftButton:
return
mimeData = QtCore.QMimeData()
mimeData.setText("Test drop")
drag = QtGui.QDrag(self)
drag.setMimeData(mimeData)
dropAction = drag.exec(QtCore.Qt.CopyAction)
要放置到的小部件:
class DropTest(QtWidgets.QWidget):
def __init__(self):
super(DropTest, self).__init__()
self.setAcceptDrops(True)
def dragEnterEvent(self, e):
print("DragEnter")
e.accept()
def dragMoveEvent(self, e):
print("DragMove")
e.accept()
def dropEvent(self, e):
print("DropEvent")
position = e.pos()
print(position)
e.accept()
当我将标签拖到另一个小部件上时,我看到 dragEnterEvent
和 dragMoveEvent
都被调用了,但是当我实际放下标签时,我没有从 dropEvent
函数。
此外,关闭 window 应用程序后将挂起并且不会退出。
我正在使用 PyQt 5.13.1 x86_64 在 Fedora 31 中安装了 DNF。Python 版本是 3.7.5,没有 virtualenv。
试一试:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class DropTest(QtWidgets.QLabel): # - QWidget + QLabel
def __init__(self):
super(DropTest, self).__init__()
self.setAcceptDrops(True)
self.setText(" Accept Drops")
self.setStyleSheet("QLabel { background-color : #ccd; color : blue; font-size: 20px;}")
def dragEnterEvent(self, e):
# print("DragEnter")
e.accept()
def dragMoveEvent(self, e):
# print("DragMove")
e.accept()
def dropEvent(self, e):
# print("DropEvent")
# position = e.pos()
# print(position)
self.setText(e.mimeData().text()) # +++
e.setDropAction(Qt.MoveAction) # +++
e.accept()
class DragLabel(QtWidgets.QLabel):
def __init__(self):
super(DragLabel, self).__init__()
self.setText("Drag me")
def mouseMoveEvent(self, e):
if e.buttons() != QtCore.Qt.LeftButton:
return
mimeData = QtCore.QMimeData()
mimeData.setText(self.text()) # ("Test drop")
drag = QtGui.QDrag(self)
drag.setMimeData(mimeData)
dropAction = drag.exec(QtCore.Qt.CopyAction)
class Win(QtWidgets.QWidget):
def __init__(self):
super(Win, self).__init__()
self.setGeometry(200, 300, 400, 200)
self.setLayout(QtWidgets.QHBoxLayout())
self.layout().addWidget(DragLabel())
self.layout().addWidget(DropTest())
if __name__ == '__main__':
app = QApplication(sys.argv)
w = Win()
w.show()
sys.exit(app.exec_())
如评论中所述,我已经在
[PyQt5] was previously installed from DNF, but I'm pretty sure setuptools also installed it from pip as a dependency of my application.
问题的原因是OP结合了两种安装方式:dnf和pip,它们分别使用不同版本的Qt、编译标志等进行编译,这可能会导致某些功能失败。解决方法是两种方法都卸载PyQt5,只重装其中一种。