Событие PyQt отправляется дважды - PullRequest
2 голосов
/ 21 июня 2011

Я пытаюсь реализовать элементы drag-n-drop'in 'от QListWidget до QGraphicsView.Я унаследовал свой собственный класс MooView от QGraphicsView и инкапсулировал события dragMove, dragEnter и drop.Но во время тестирования я заметил, что каждое событие генерируется дважды.

Вот мой 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 Ответ

2 голосов
/ 21 июня 2011

Как я читал где-то в сети, QGraphicsView может передавать события в QGraphicsScene в некоторых случаях. Так оно и было здесь: когда я унаследовал свой класс от QGraphicsScene и использовал его по умолчанию для QGraphicsView (заменил MooView на QGraphicsView; прочтите остальную часть этого ответа для деталей), он работал так, как я ожидал. 1007 *

Итак, теперь у меня есть две части источника: MooGraphicsScene.py и main.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_())

Надеюсь, это кому-нибудь поможет!

...