2011-06-21 33 views
2

我试图实现从QListWidgetQGraphicsView的drag-n-drop-in'项目。我从QGraphicsView继承了我自己的MooView类,并封装了dragMove,dragEnterdrop事件。但是在测试这个时候,我注意到每个事件都被排除了两次。PyQt event committed两次

这里是我的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 

问题是:如何可以修复?

回答

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_()) 

希望,这将帮助别人!