PyQt 事件发出两次 [英] PyQt event emmitted twice

查看:90
本文介绍了PyQt 事件发出两次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现从 QListWidgetQGraphicsView 的拖放项目.我从 QGraphicsView 继承了我自己的类 MooView 并封装了 dragMovedragEnterdrop事件.但是在对此进行测试时,我注意到每个事件都发出了两次.

I'm trying to implement drag-n-drop'in' items from QListWidget to QGraphicsView. I've inherited my own class MooView from QGraphicsView and encapsulated dragMove, dragEnter and drop events. But while testing this out, i've noticed that each event is emmitted twice.

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

这就是我运行该核心的方式:

And this is how i run that core:

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

拖放项目时,项目拖入"和项目放下"行在终端中各打印两次,例如:

When drag-n-dropping items, "item drag enter" and "item dropped" lines are printed twice each in the terminal, e.g.:

item drag enter 
item drag enter 
item dropped 
item dropped

问题是:如何修复???

推荐答案

正如我在网上看到的,QGraphicsView 可以在某些情况下将事件传递给它的 QGraphicsScene案件.所以它在这里做到了:当我从 QGraphicsScene 继承我的类并将其用作 QGraphicsView 的默认值(用 QGraphicsView 替换 MooView代码>;阅读此答案的其余部分以了解详细信息)它按我的预期工作.

As i've read somewhere in the web, QGraphicsView could pass events to its QGraphicsScene in some cases. So it did here: when i inherited my class from QGraphicsScene and used it as default for QGraphicsView (replaced MooView with QGraphicsView; read the rest of this answer for details) it worked as i was expecting.

所以,现在我有两个源代码部分:MooGraphicsScene.pymain.py.它们分别是:

So, now i have two source parts: MooGraphicsScene.py and main.py. Here are they, respectively:

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

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

Hope, this would help someone!

这篇关于PyQt 事件发出两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆