События с QGraphicsItemGroup
В моем приложении я хочу использовать QGraphicsItemGroup для группировки элементов в один элемент.
Я немного поиграл с этим и не уверен, что использую его, потому что когда я хочу поймать события, события объединяются вместе, но я хочу обработать конкретное событие с конкретным потомком.
Как мне этого добиться?
2 ответа
Вам нужно позвонить QGraphicsItemGroup::setHandlesChildEvents(false)
, Это останавливает QGraphicsItemGroup
пытается обработать событие, и позволяет ребенку QGraphicsItem
вместо этого справиться с ними.
Я думаю, что это точка QGraphicsItemGroup
, Судя по документации, это должно упростить перемещение и преобразование нескольких элементов одновременно, например, представьте следующий случай: пользователь рисует прямоугольник выбора вокруг нескольких элементов в приложении, потому что он хочет переместить все их. Возможно, вам нужно создать иерархию элементов, например, иметь один родительский элемент с несколькими дочерними элементами. Таким образом, вы получите отдельные события для каждого элемента. Это можно сделать, позвонив QGraphicsItem::setParentItem()
;
Вопрос не указывает, какая версия Qt касается, и есть правильный ответ для Qt4. Вот ответ для Qt5 (он работает для PyQt5, и я думаю, он будет работать и на C++). Решением было переопределитьsceneEvent
, переопределив специализированный ловец событий, такой как contextMenuEvent
было недостаточно.
#!/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_())