Search code examples
pythonpyqtpyqt4

How to create circular image using pyqt4?


Here I wrote this code but did not work:

import sys
from PyQt4 import QtGui, QtCore

class CricleImage(QtCore.QObject):
    def __init__(self):
        super(CricleImage, self).__init__()

        self.pix = QtGui.QGraphicsPixmapItem(QtGui.QPixmap("bird(01).jpg"))

        #drawRoundCircle
        rect = self.pix.boundingRect()
        self.gri = QtGui.QGraphicsRectItem(rect)
        self.gri.setPen(QtGui.QColor('red'))


if __name__ == '__main__':

    myQApplication = QtGui.QApplication(sys.argv)

    IMG = CricleImage()
    #scene
    scene = QtGui.QGraphicsScene(0, 0, 400, 300)
    scene.addItem(IMG.pix)
    #view
    view = QtGui.QGraphicsView(scene)
    view.show()
    sys.exit(myQApplication.exec_())

Solution

  • One possible solution is to overwrite the paint() method of the QGraphicsPixmapItem and use setClipPath to restrict the painting region:

    from PyQt4 import QtCore, QtGui
    
    
    class CirclePixmapItem(QtGui.QGraphicsPixmapItem):
        @property
        def radius(self):
            if not hasattr(self, "_radius"):
                self._radius = 0
            return self._radius
    
        @radius.setter
        def radius(self, value):
            if value >= 0:
                self._radius = value
                self.update()
    
        def paint(self, painter, option, widget=None):
            painter.save()
            rect = QtCore.QRectF(QtCore.QPointF(), 2 * self.radius * QtCore.QSizeF(1, 1))
            rect.moveCenter(self.boundingRect().center())
            path = QtGui.QPainterPath()
            path.addEllipse(rect)
            painter.setClipPath(path)
            super().paint(painter, option, widget)
            painter.restore()
    
    
    if __name__ == "__main__":
        import sys
    
        app = QtGui.QApplication(sys.argv)
    
        pixmap = QtGui.QPixmap("logo.jpg")
    
        scene = QtGui.QGraphicsScene()
        view = QtGui.QGraphicsView(scene)
        view.setRenderHints(
            QtGui.QPainter.Antialiasing | QtGui.QPainter.SmoothPixmapTransform
        )
    
        it = CirclePixmapItem(pixmap)
        scene.addItem(it)
    
        it.radius = pixmap.width() / 2
    
        view.show()
        sys.exit(app.exec_())
    

    enter image description here

    Update:

    # ...
    view = QtGui.QGraphicsView(
        scene, alignment=QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft
    )
    # ...
    view.show()
    it.setPos(80, 80)
    sys.exit(app.exec_())