PyQt事件两次被发送

时间:2011-06-21 11:19:16

标签: python qt pyqt signals

我正在尝试实施从QListWidgetQGraphicsView的“拖放”项目。我从MooView继承了我自己的课程QGraphicsView,并封装了dragMovedragEnterdrop个事件。但是在测试时,我注意到每个事件都被两次激活。

这是我的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 个答案:

答案 0 :(得分:2)

正如我在网络上的某处读到的那样,QGraphicsView可能会在某些情况下将事件传递给QGraphicsScene。所以它在这里做了:当我从QGraphicsScene继承我的课程并将其用作QGraphicsView的默认课程时(用MooView替换QGraphicsView;有关详细信息,请阅读本答案的其余部分)它像我期待的那样奏效。

所以,现在我有两个源部分:MooGraphicsScene.pymain.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_())

希望,这会对某人有所帮助!