pythonpyqtpyqt4qgraphicspixmapitem

Is it possible to attach one QGraphicsPixmapItem to another?


I'm currently working with PyQt4 in Python and I haven't been able to find anything online about combining 2 different items in a GraphicsView class on a PyQt UI together. Is this possible?

The goal is to anchor one QGraphicsPixmapItem to another inside a GraphicsView class, so that when one's position is changed or it is rotated, the other follows. More importantly, is it possible for one QGraphicsPixmapItem to be anchored to a specific location on another? E.g. the edge, so that when the other graphics item is rotated or moved, the anchored one will remain in the exact location relative to the moving item.


Solution

  • If you want an item not to change its position with respect to another item when the last item rotates or moves then it is only enough that the first item is the child of the second item:

    import random
    import sys
    
    from PyQt4 import QtCore, QtGui
    
    
    def create_pixmap(size):
        pixmap = QtGui.QPixmap(size)
        pixmap.fill(QtGui.QColor(*random.sample(range(255), 3)))
        return pixmap
    
    
    class VariantAnimation(QtCore.QVariantAnimation):
        def updateCurrentValue(self, value):
            pass
    
    
    if __name__ == "__main__":
    
        app = QtGui.QApplication(sys.argv)
    
        w = QtGui.QMainWindow()
    
        scene = QtGui.QGraphicsScene(w)
        view = QtGui.QGraphicsView(scene)
    
        parent_item = scene.addPixmap(create_pixmap(QtCore.QSize(150, 150)))
        parent_item.setTransformOriginPoint(parent_item.boundingRect().center())
        parent_item.setFlag(QtGui.QGraphicsItem.ItemIsMovable, True)
    
        child_item = QtGui.QGraphicsPixmapItem(
            create_pixmap(QtCore.QSize(70, 70)), parent_item
        )
        # or
        # child_item = QtGui.QGraphicsPixmapItem(create_pixmap(QtCore.QSize(70, 70)))
        # child_item.setParentItem(parent_item)
    
        animation = VariantAnimation(
            startValue=0, endValue=360, duration=1000, loopCount=-1
        )
        animation.valueChanged.connect(parent_item.setRotation)
        animation.start()
    
        w.setCentralWidget(view)
        w.resize(640, 480)
        w.show()
    
        sys.exit(app.exec_())