2011-06-21 31 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_()) 

希望,這將幫助別人!