Events with QGraphicsItemGroup

后端 未结 3 1816
忘掉有多难
忘掉有多难 2020-12-20 12:22

In my application I want to use QGraphicsItemGroup for grouping items into one item.
I played with it a little and not sure using it because when I want to catch events

相关标签:
3条回答
  • 2020-12-20 12:58

    You need to call QGraphicsItemGroup::setHandlesChildEvents(false). This stops the QGraphicsItemGroup trying to handle the event, and lets the child QGraphicsItems handle them instead.

    0 讨论(0)
  • 2020-12-20 13:03

    I think that's the point of the QGraphicsItemGroup. Judging from the documentation, this is meant to simplify moving and transforming multiple items at once e.g. imagine the following case: a user draws a selection rectangle around several items in an application because he wants to move all of them. Perhaps what you want more is to create a hierarchy of items, e.g. have one parent item with several child items. This way you'll get the individual events for each item. This can be accomplished by calling QGraphicsItem::setParentItem();

    0 讨论(0)
  • 2020-12-20 13:23

    The question doesn't specify which version of Qt is concerned and there is a correct answer for Qt4. Here is an answer for Qt5 (it works for PyQt5 and I guess it'll work also in C++). The solution was to reimplement sceneEvent, reimplementing a specialized event-catcher such as contextMenuEvent was not sufficient.

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    from PyQt5 import QtCore
    from PyQt5 import QtGui
    from PyQt5 import QtWidgets
    
    
    class GraphicsItem(QtWidgets.QGraphicsItem):
        def __init__(self,
                   rect: QtCore.QRectF,
                   name: str,
                   parent: QtWidgets.QGraphicsItem = None):
            super().__init__(parent)
            self._name = name
            self._rect = rect
    
        def boundingRect(self):
            return self._rect
    
        def paint(self,
                  painter: QtGui.QPainter,
                  option: QtWidgets.QStyleOptionGraphicsItem,
                  widget: QtWidgets.QWidget = None):
            painter.setPen(QtGui.QPen(QtCore.Qt.NoPen))
            painter.setBrush(QtGui.QBrush(QtCore.Qt.red))
            painter.drawRect(self._rect)
    
        def sceneEvent(self, event: QtCore.QEvent):
            if (event.type() == QtCore.QEvent.GraphicsSceneContextMenu):
                self.contextMenuEvent(event)
            event.accept()
            return True
    
        def contextMenuEvent(self, event: QtWidgets.QGraphicsSceneContextMenuEvent):
            print(f'contextMenuEvent in "{self._name}"')
    
    
    class MainWindow(QtWidgets.QMainWindow):
        def __init__(self):
            super().__init__()
    
            self._scene = QtWidgets.QGraphicsScene()
    
            layout = QtWidgets.QHBoxLayout()
            self._view = QtWidgets.QGraphicsView(self._scene)
            layout.addWidget(self._view)
    
            self._widget = QtWidgets.QWidget()
            self._widget.setLayout(layout)
    
            group = QtWidgets.QGraphicsItemGroup()
            self._scene.addItem(group)
    
            scene_item = GraphicsItem(QtCore.QRectF(0, 0, 100, 100), 'in scene')
            self._scene.addItem(scene_item)
    
            group_item = GraphicsItem(QtCore.QRectF(150, 0, 100, 100), 'in group')
            group.addToGroup(group_item)
    
            group_item = GraphicsItem(QtCore.QRectF(300, 0, 100, 100), '2nd in group')
            group.addToGroup(group_item)
    
            self.setCentralWidget(self._widget)
            self.setWindowTitle('contextMenuEvent with QGraphicsItemGroup')
    
    
    if __name__ == '__main__':
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
    
        mainWindow = MainWindow()
        mainWindow.setGeometry(100, 100, 800, 500)
        mainWindow.show()
    
        sys.exit(app.exec_())
    
    0 讨论(0)
提交回复
热议问题