PyQt:QGraphicsScene事件不会传播到GraphicItems

时间:2012-08-28 14:45:59

标签: python events pyqt qgraphicsitem

我在QGraphicView中有一个GraphicScene,里面有许多矩形(项目)。我希望每个矩形都能响应鼠标单击但我无法找到钩子将事件处理程序附加到正确的对象并将事件传播给它。

我在场景中附加了一个事件处理程序:

scene.event = myfunction

它工作(它正在触发每个事件)但我无法将相同的功能附加到其中一个孩子。你能告诉我在哪里搜索这样一个入口点吗?

2 个答案:

答案 0 :(得分:3)

所以 - 我不确定你在那里做了什么,但我想不出在PyQt中你应该将自定义函数直接映射到场景的事件方法。

你有一个实际的例子吗?

如果你正在做:

scene.mousePressEvent = my_mouse_function

那不是你想要的方式。

您可以考虑使用事件过滤器(http://doc.qt.nokia.com/4.7-snapshot/eventsandfilters.html#event-filters)。

获得你想要的东西的最好方法是继承QGraphicsItem(你正在使用的任何一个 - QGraphicsRectItem,QGraphicsPathItem等)并在其上重载mousePressEvent方法。

http://doc.qt.nokia.com/4.7-snapshot/qgraphicsitem.html#mousePressEvent

例如:

from PyQt4.QtGui import QGraphicsRectItem

class MyItem(QGraphicsRectItem):
    def mousePressEvent(self, event):
        super(MyItem, self).mousePressEvent(event)
        print 'overloaded'

scene.addItem(MyItem())

答案 1 :(得分:2)

将视图,场景,项目等子类化,然后重新实现mousePressEvent和/或mouseReleaseEvent;或者在这些项目上安装event filter

有关在场景中使用事件过滤器的示例,请参阅this answer

这是一个在视图上重新实现mouseReleaseEvent的演示:

from PyQt4 import QtGui, QtCore

class Window(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.view = View(self)
        self.label = QtGui.QLabel(self)
        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.view)
        layout.addWidget(self.label)

class View(QtGui.QGraphicsView):
    def __init__(self, parent):
        QtGui.QGraphicsView.__init__(self, parent)
        self.setScene(QtGui.QGraphicsScene(self))
        for index, name in enumerate('One Two Three Four Five'.split()):
            item = QtGui.QGraphicsRectItem(
                index * 60, index * 60, 50, 50)
            item.setData(0, name)
            self.scene().addItem(item)

    def mouseReleaseEvent(self, event):
        pos = event.pos()
        item = self.itemAt(pos)
        if item is not None:
            text = 'Rectangle <b>%s</b>' % item.data(0).toString()
        else:
            text = 'No Rectangle (%d, %d)' % (pos.x(), pos.y())
        self.parent().label.setText(text)
        QtGui.QGraphicsView.mouseReleaseEvent(self, event)

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.resize(400, 400)
    window.show()
    sys.exit(app.exec_())