Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Arrow with control point children, how to keep arrow position centered?



  • Hello. My code is way to involved to minimize for us. Does anyone have experience keeping the position of an item updated, when it's apparent "position" is governed by some of its children?

    I'm returning childrenBoundingRect() for boundingRect() of the arrows.

    The above code gets called whenever a control point moves by any small iota. However, it doesn't do what you'd expect. It causes the control points to jump around and orbit other points.

    All I want to do is take the center position of all the control points (speaking absolutely here in terms of position coordinates)
    update the arrow position to be the center, and of course apply the opposite delta to all the points again so they don't move at all when viewing them. The last step is crucial since child position is relative to parent, so if I update the parent position, I need to compensate by doing the opposite to all the child positions.

    def update_centroid_pos(self):
            self._updatingPointPos = True
            center = self.point_center()
            delta = self.mapToParent(center) - self.pos()
            self.setPos(center)
            delta = self.mapFromParent(-delta)
            for point in self._points:
                point.setPos(point.pos() + delta)
            self._updatingPointPos = False
    

    If I leave it alone, the arrows appear like they're working correctly except for the fact that the bounding rect is "way over there" when I open up my graphical debug tool on it.

    So the app works, but upon pickling / unpickling the bug shows up. It appears to be a boundingRect / rendering related bug, so fixing this centroid position issue is vital.


  • Lifetime Qt Champion

    Hi,

    You might want to explain a bit more what you are currently moving around. QWidgets ? QGraphicsViewItem ? Something else ?



  • The items being moved are QGraphicsObject subclasses Arrow together with their ControlPoint's.

    This code works:

    def update_centroid_pos(self):
        if not self._updatingPointPos:
            self._updatingPointPos = True
            center = self.point_center()
            delta = self.mapFromParent(self.pos()) - center 
            for point in self._points:
                point.setPos(point.pos() + delta)
            self.setPos(self.mapToParent(center))                
            self._updatingPointPos = False
    

    However, it doesn't support press-moving. What happens is the control point moves twice as far as it should and so shows an accelerating movement while the cursor moves at a constant rate. So I just changed my scene editing to be the same as when you place a ControlPoint : it's held under cursor until the user presses again. This works for my purposes.


Log in to reply