PyQt 事件发出两次 [英] PyQt event emmitted twice
问题描述
我正在尝试实现从 QListWidget
到 QGraphicsView
的拖放项目.我从 QGraphicsView
继承了我自己的类 MooView
并封装了 dragMove
、dragEnter
和 drop代码>事件.但是在对此进行测试时,我注意到每个事件都发出了两次.
I'm trying to implement drag-n-drop'in' items from QListWidget
to QGraphicsView
. I've inherited my own class MooView
from QGraphicsView
and encapsulated dragMove
, dragEnter
and drop
events. But while testing this out, i've noticed that each event is emmitted twice.
这是我的 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
这就是我运行该核心的方式:
And this is how i run that core:
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_())
拖放项目时,项目拖入"和项目放下"行在终端中各打印两次,例如:
When drag-n-dropping items, "item drag enter" and "item dropped" lines are printed twice each in the terminal, e.g.:
item drag enter
item drag enter
item dropped
item dropped
问题是:如何修复???
推荐答案
正如我在网上看到的,QGraphicsView
可以在某些情况下将事件传递给它的 QGraphicsScene
案件.所以它在这里做到了:当我从 QGraphicsScene
继承我的类并将其用作 QGraphicsView
的默认值(用 QGraphicsView
替换 MooView
代码>;阅读此答案的其余部分以了解详细信息)它按我的预期工作.
As i've read somewhere in the web, QGraphicsView
could pass events to its QGraphicsScene
in some cases. So it did here: when i inherited my class from QGraphicsScene
and used it as default for QGraphicsView
(replaced MooView
with QGraphicsView
; read the rest of this answer for details) it worked as i was expecting.
所以,现在我有两个源代码部分:MooGraphicsScene.py
和 main.py
.它们分别是:
So, now i have two source parts: MooGraphicsScene.py
and main.py
. Here are they, respectively:
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_())
希望,这会对某人有所帮助!
Hope, this would help someone!
这篇关于PyQt 事件发出两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!