Let me explain my problem in detail. I have a QGraphicsRectItem as a parent in QGraphicsScene, and I have QGraphicsPolygonItems as its children. When The children are not selected and I move the parent everything's fine - they keep their positions relative to the parent and move with it. But when children are selected and I move the parent children move weirdly (I would like them to behave the same way as if they were not selected - move relative to their parent). Here's the code and a gif displaying both situations.
class Test(QWidget):
def __init__(self, parent=None):
super(Test, self).__init__(parent)
self.resize(1000, 800)
self.generalLayout = QVBoxLayout()
self.view_ = GraphicsView()
self.size_grip = QSizeGrip(self)
self.generalLayout.addWidget(self.size_grip, 0, Qt.AlignBottom | Qt.AlignRight)
self.generalLayout.addWidget(self.view_)
self.setLayout(self.generalLayout)
def contextMenuEvent(self, event):
self.menu = QMenu(self)
self.new_children_menu = QMenu("New child", self.menu)
parentAction = QAction("New Parent", self)
childAction = QAction('Child', self)
click_pos = self.view_.mapToScene(event.pos())
parent_item = self.itemUnderMouse()
mouse_pos = self.mousePosition(click_pos, parent_item)
parentAction.triggered.connect(lambda: self.view_.addParent(mouse_pos, parent_item))
childAction.triggered.connect(lambda: self.view_.addButton(mouse_pos, parent_item))
self.new_children_menu.addAction(childAction)
self.menu.addAction(parentAction)
self.menu.addMenu(self.new_children_menu)
self.menu.popup(QCursor.pos())
def mousePosition(self, click, prnt_item):
if prnt_item is None:
return click
else:
return prnt_item.mapFromScene(click)
def itemUnderMouse(self):
for item in self.view_.scene().items():
if item.isUnderMouse():
return item
else:
continue
class GraphicsView(QGraphicsView):
def __init__(self):
super(GraphicsView, self).__init__()
self.setAttribute(Qt.WA_StyledBackground, True)
self.setStyleSheet('background-color: white;')
self.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform)
self.setMouseTracking(True)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.setFrameShape(QFrame.NoFrame)
self.setCursor(QCursor(Qt.PointingHandCursor))
self.size_grip = QSizeGrip(self)
self._scene = QGraphicsScene()
self._scene.setSceneRect(0, 0, 400, 400)
self.setScene(self._scene)
self.fitInView(self.scene().sceneRect(), Qt.KeepAspectRatio)
self.setDragMode(QGraphicsView.ScrollHandDrag)
self.parent = GraphicsRectItem
self.child = newButton
def addParent(self, pos, prnt):
new_parent = self.parent(0, 0, 100, 150)
new_parent.setPos(pos)
if prnt is None:
self.scene().addItem(new_parent)
else:
new_parent.setParentItem(prnt)
def addButton(self, pos, parent_item):
new_button = self.child(pos)
if parent_item is None:
self.scene().addItem(new_button)
else:
new_button.setParentItem(parent_item)
class GraphicsRectItem(QGraphicsRectItem):
def __init__(self, *args):
super().__init__(*args)
self.setAcceptHoverEvents(True)
self.setFlag(QGraphicsItem.ItemIsMovable, True)
self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True)
self.setFlag(QGraphicsItem.ItemIsFocusable, True)
class newButton(QGraphicsPolygonItem):
def __init__(self, pos):
super(newButton, self).__init__()
self.newPoly = QPolygonF()
self.newPolyPoints = (QPointF(0, 0),
QPointF(0, 50),
QPointF(50, 50),
QPointF(50, 0))
for point in self.newPolyPoints:
self.newPoly.append(point)
self.setPolygon(self.newPoly)
self.setBrush(QBrush(QColor("violet")))
self.setPen(QPen(QColor("gray")))
self.setFlags(
self.ItemIsSelectable
| self.ItemIsMovable
| self.ItemIsFocusable
| self.ItemSendsGeometryChanges
)
self.setAcceptHoverEvents(True)
poly_center = self.boundingRect().center()
self.setTransformOriginPoint(poly_center)
self.setPos(pos)
if __name__ == '__main__':
app = QApplication([])
win = Test()
win.show()
app.exec_()
I also want the children to not go out of the parent's bounding rectangle area, but if I set the "ItemClipsChildrenToShape" flag the children disappear inside the parent. This gif illustrates that situation.