[Interest] How to change parent of scaled QGraphicsItem while retaining scene bounding rect?

Patrick Stinson patrickkidd at gmail.com
Thu Aug 9 05:42:36 CEST 2018


I got a little further, this snippet works when the parent items don’t have a scale set. But when the parents do have a scale set the child item’s position jumps around a bit when changing parents.

    def setParent(parent):
	if parent == child.parentItem():
            return

        if not child.parentItem() and parent:
            st = child.sceneTransform() # I assume even if the child has a parent.                                                                                                
            inverted, ok = parent.sceneTransform().inverted()
            lt = inverted * st
        elif child.parentItem() and not parent:
            lt = child.sceneTransform()
        elif child.parentItem() and parent:
            st = child.sceneTransform()
            inverted, ok = parent.sceneTransform().inverted()
            lt = inverted * st
        child.setTransform(lt)
        child.setScale(1.0)
        child.setRotation(0.0)
        child.setParentItem(parent)

> On Aug 8, 2018, at 10:42 AM, Patrick Stinson <patrickkidd at gmail.com> wrote:
> 
> Thanks for that. Though I am having some trouble. If you have PyQt, I wonder what problem you see with this example:
> 
> def tests_QGI_parent_transform():
>     app = QApplication(sys.argv)
>     view = QGraphicsView()
> 
>     scene = QGraphicsScene()
>     rect = QRectF(-50.0, -50.0, 100.0, 100.0)
> 
>     parentA = QGraphicsRectItem(rect) # red                                                                                                                                                                                                   
>     parentA.setPos(-100, -100)
>     parentA.setScale(.5)
>     parentA.setPen(Qt.red)
>     scene.addItem(parentA)
> 
>     parentB = QGraphicsRectItem(rect) # blue                                                                                                                                                                                                  
>     parentB.setPos(100, 100)
>     parentB.setScale(1.0)
>     parentB.setPen(Qt.blue)
>     scene.addItem(parentB)
> 
>     child = QGraphicsRectItem(rect) # green                                                                                                                                                                                                   
>     child.setPos(-100, 100)
>     child.setPen(Qt.green)
>     scene.addItem(child)
>     view.setScene(scene)
> 
>     buttonParent = QWidget(view)
>     parentAButton = QPushButton('Set Parent A', buttonParent)
>     parentBButton = QPushButton('Set Parent B', buttonParent)
>     noParentButton = QPushButton('Set No Parent', buttonParent)
>     ButtonLayout = QVBoxLayout(buttonParent)
>     ButtonLayout.addWidget(parentAButton)
>     ButtonLayout.addWidget(parentBButton)
>     ButtonLayout.addWidget(noParentButton)
>     buttonParent.move(10, 10)
>     def setParent(parent):
>         if parent == child.parentItem():
>             return
>         sceneTransform = child.sceneTransform() # I assume even if the child has a parent.                                                                                                                                                    
>         if parent:
>             inverted, ok = parent.sceneTransform().inverted()
>             localTransform = inverted * sceneTransform
>             print(parent.pen().color().name())
>         else:
>             localTransform = sceneTransform
>         child.setTransform(localTransform)
>         child.setScale(1.0)
>         child.setRotation(0.0)
>         child.setParentItem(parent)
>     parentAButton.clicked.connect(lambda: setParent(parentA))
>     parentBButton.clicked.connect(lambda: setParent(parentB))
>     noParentButton.clicked.connect(lambda: setParent(None))
> 
>     view.resize(800, 600)
>     r = scene.itemsBoundingRect()
>     sceneRect = r.marginsAdded(QMarginsF(r.x() * 2,
>                                          r.y() * 2,
>                                          r.width() * 2,
>                                          r.height() * 2))
>     view.fitInView(sceneRect)
>     view.centerOn(0, 0)
>     view.show()
>     app.exec()
> 
> 
> tests_QGI_parent_transform()
> 
> 
> 
> 
>> On Aug 7, 2018, at 10:05 PM, Christian Gagneraud <chgans at gmail.com <mailto:chgans at gmail.com>> wrote:
>> 
>> On 8 August 2018 at 15:49, Patrick Stinson <patrickkidd at gmail.com <mailto:patrickkidd at gmail.com>> wrote:
>>> Thanks for the reply. I am just particularly dense in this sort of cognitive operation (something about flipping symbolic representations like in fractional arithmetic) and might do well with just a bit of code or pseudo code. Do you think you might provide some?
>> 
>> I haven't done graphics stuff in a while (unfortunately), but this
>> should be as simple as:
>> scene_xform = item->sceneTransform();
>> local_xform = next_parent->sceneTransform().inverted() * scene_xform;
>> item.setTransform(local_xform);
>> item.setScale(1.0);
>> item.setRotation(0.0);
>> item.setParentItem(next_parent);
>> 
>> AFAIR, QGI's rotation and scale need to be reset b/c they are combined
>> with QGI's transform()
>> 
>> Hope this help!
>> Chris
>> 
>>> 
>>> Thanks!
>>> 
>>>> On Aug 7, 2018, at 6:24 PM, Christian Gagneraud <chgans at gmail.com <mailto:chgans at gmail.com>> wrote:
>>>> 
>>>> On 8 August 2018 at 11:08, Patrick Stinson <patrickkidd at gmail.com <mailto:patrickkidd at gmail.com>> wrote:
>>>>> Hello!
>>>>> 
>>>>> I am trying to change the parent of a QGraphicsItem without it appearing to move or change size on the scene. Both the item, old parent, and new have arbitrary scale values set. How can this be done?
>>>> 
>>>> If you grab the item's sceneTransform() before re-parenting, you
>>>> should be able to deduce it's new local transform from it's new parent
>>>> sceneTransform().
>>>> 
>>>> 
>>>>> 
>>>>> Thanks!
>>>>> _______________________________________________
>>>>> Interest mailing list
>>>>> Interest at qt-project.org <mailto:Interest at qt-project.org>
>>>>> http://lists.qt-project.org/mailman/listinfo/interest
>>> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20180808/f17ac9da/attachment.html>


More information about the Interest mailing list