2011-06-21 15 views
2

QListWidgetからQGraphicsViewまでドラッグアンドドロップを実装しようとしています。私は自分のクラスMooViewQGraphicsViewから継承し、dragMove,dragEnterおよびdropイベントをカプセル化しました。しかし、これをテストしている間、私は各イベントが2回出されたことに気づいた。PyQtイベントが2回発行されました

はここに私の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_()) 

ドラッグアンドドロップするアイテムは、「アイテムのドラッグが入る」と「アイテムがドロップされました」線は、端末内でそれぞれ2回印刷されます。例:

item drag enter 
item drag enter 
item dropped 
item dropped 

質問は:どのように修正することができましたか?

答えて

2

ウェブのどこかで読んだことがあるように、QGraphicsViewは場合によってはQGraphicsSceneにイベントを渡すことができます。だから、私はクラスを継承してQGraphicsSceneからデフォルトで使用し、QGraphicsView(をQGraphicsViewに置き換えました;詳細はこの回答の残りを読んでください)は、私が期待していたように機能しました。

これで2つのソース部分があります: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!") 

そして、この1:

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

ホープこれは誰かに役立つだろう!

関連する問題