PyQt事件被触发两次
我正在尝试实现将项目从 QListWidget
拖放到 QGraphicsView
的功能。我创建了一个自己的类 MooView
,这个类是从 QGraphicsView
继承来的,并且我封装了 dragMove
、dragEnter
和 drop
这些事件。但是在测试的时候,我发现每个事件都被触发了两次。
这是我的 MooView
的代码:
from PyQt4 import QtCore, QtGui
class MooView(QtGui.QGraphicsView):
def __init__(self, parent = None):
QtGui.QGraphicsView.__init__(self, parent)
self.handlers = {}
self.handlers['dragEnter'] = []
self.handlers['dragEnter'].append(super(MooView, self).dragEnterEvent)
self.handlers['dragLeave'] = []
self.handlers['dragLeave'].append(super(MooView, self).dragLeaveEvent)
self.handlers['dragMove'] = []
self.handlers['dragMove'].append(super(MooView, self).dragMoveEvent)
self.handlers['drop'] = []
self.handlers['drop'].append(super(MooView, self).dropEvent)
def addDragEnterHandler(self, handler):
self.handlers['dragEnter'].append(handler)
def removeDragEnterHandler(self, handler):
self.handlers['dragEnter'].remove(handler)
def addDragLeaveHandler(self, handler):
self.handlers['dragLeave'].append(handler)
def removeDragLeaveHandler(self, handler):
self.handlers['dragLeave'].remove(handler)
def addDragMoveHandler(self, handler):
self.handlers['dragMove'].append(handler)
def removeDragMoveHandler(self, handler):
self.handlers['dragMove'].remove(handler)
def addDropHandler(self, handler):
self.handlers['drop'].append(handler)
def removeDropHandler(self, handler):
self.handlers['drop'].remove(handler)
# handlers
def dragEnterEvent(self, arg):
#res = super(MooView, self).dragEnterEvent(arg)
for h in self.handlers['dragEnter']:
h(arg)
#return res
def dragLeaveEvent(self, arg):
#res = super(MooView, self).dragLeaveEvent(arg)
for h in self.handlers['dragLeave']:
h(arg)
#return res
def dragMoveEvent(self, arg):
#res = super(MooView, self).dragMoveEvent(arg)
for h in self.handlers['dragMove']:
h(arg)
#return res
def dropEvent(self, arg):
#res = super(MooView, self).dropEvent(arg)
for h in self.handlers['drop']:
h(arg)
#return res
这是我运行这个核心功能的方式:
import sys
from PyQt4 import QtCore, QtGui, QtOpenGL
from window import Ui_MainWindow
class Main(QtGui.QMainWindow):
def __init__(self, parent = None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.setWindowTitle('Hello, Qt!')
self.scene = QtGui.QGraphicsScene()
self.ui.workspace_view.setScene(self.scene)
rect = QtCore.QRectF(0, 0, 1000, 1000)
self.scene.setSceneRect(0, 0, rect.width(), rect.height())
self.ui.workspace_view.setViewport(QtOpenGL.QGLWidget())
icon = QtGui.QIcon(QtGui.QPixmap(":/Images/50.png"))
text = "50's element"
item = QtGui.QListWidgetItem(icon, text)
self.ui.element_list.addItem(item)
icon = QtGui.QIcon(QtGui.QPixmap(":/Images/40.png"))
text = "40's element"
item = QtGui.QListWidgetItem(icon, text)
self.ui.element_list.addItem(item)
self.ui.workspace_view.addDragEnterHandler(self.workspace_item_drag_enter)
self.ui.workspace_view.addDragMoveHandler(self.workspace_item_drag_move)
self.ui.workspace_view.addDropHandler(self.workspace_item_dropped)
def workspace_item_drag_move(self, e):
#print("item drag move")
e.accept()
def workspace_item_drag_enter(self, e):
print("item drag enter")
e.accept()
def workspace_item_dropped(self, e):
print("item dropped")
if (__name__ == "__main__"):
app = QtGui.QApplication(sys.argv)
myApp = Main()
myApp.show()
sys.exit(app.exec_())
在拖放项目的时候,终端里会打印出“项目拖入”和“项目已放下”的信息,每条信息都会打印两次,例如:
item drag enter
item drag enter
item dropped
item dropped
问题是:这个怎么解决呢???
1 个回答
2
我在网上看到过,QGraphicsView
在某些情况下可以把事件传递给它的 QGraphicsScene
。在我的例子中就是这样:当我让我的类继承自 QGraphicsScene
并把它作为 QGraphicsView
的默认设置时(把 MooView
替换成了 QGraphicsView
;想了解更多细节可以看下面的内容),它的表现正如我所期待的那样。
现在,我有两个源文件:MooGraphicsScene.py
和 main.py
。它们分别是:
from PyQt4 import QtCore, QtGui
class MooGraphicsScene(QtGui.QGraphicsScene):
def __init__(self, parent = None):
QtGui.QGraphicsScene.__init__(self, parent)
def dragMoveEvent(selfs, e):
pass
def dropEvent(self, e):
print("Drop fired!")
def dragEnterEvent(self, e):
e.accept()
print("Drag entered!")
还有这个:
import sys
from PyQt4 import QtCore, QtGui, QtOpenGL
from window import Ui_MainWindow
from MooGraphicsScene import MooGraphicsScene
class Main(QtGui.QMainWindow):
def __init__(self, parent = None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.setWindowTitle('Hello, Qt!')
# Setup Workspace
self.scene = MooGraphicsScene()
self.ui.workspace_view.setScene(self.scene)
rect = QtCore.QRectF(0, 0, 1000, 1000)
self.scene.setSceneRect(0, 0, rect.width(), rect.height())
icon = QtGui.QIcon(QtGui.QPixmap(":/Images/50.png"))
text = "50's element"
item = QtGui.QListWidgetItem(icon, text)
self.ui.element_list.addItem(item)
icon = QtGui.QIcon(QtGui.QPixmap(":/Images/40.png"))
text = "40's element"
item = QtGui.QListWidgetItem(icon, text)
self.ui.element_list.addItem(item)
if (__name__ == "__main__"):
app = QtGui.QApplication(sys.argv)
myApp = Main()
myApp.show()
sys.exit(app.exec_())
希望这能对某些人有所帮助!