2

I have image that needs to be annotated ie; I should be able to draw a rectangle or a polygon or any kind of shape like using pen.

What libraries can be used in Pyqt4?

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
user1050619
  • 19,822
  • 85
  • 237
  • 413

1 Answers1

3

There are 2 possible solutions:

  • Create a class that inherits from a QLabel or QWidget and overwrite the paintEvent method.

  • Use QGraphicsView and add QGraphicsItem that represent those characteristics.

The second solution I think is the best so it's the one I've implemented.

import sys

import math

from PyQt4.QtCore import *
from PyQt4.QtGui import * 


class Widget(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        self.btn = QPushButton("Press Me")

        self.gv = QGraphicsView()
        self.scene = QGraphicsScene(self)
        self.gv.setScene(self.scene) 
        self.gv.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform)

        lay = QVBoxLayout(self)
        lay.addWidget(self.btn)
        lay.addWidget(self.gv)

        self.p_item = self.scene.addPixmap(QPixmap("lena.png"))
        self.p_item.setPos(100, 100)

        self.btn.clicked.connect(self.print_)
        self.emulate_drawing()

    def emulate_drawing(self):
        rect = self.p_item.boundingRect()

        path = QPainterPath()
        A = rect.height()

        for i in range(0, int(rect.width())-10):
            path.lineTo(i, A/2*(1-math.cos(i*math.pi/40)))

        item = QGraphicsPathItem(path, self.p_item)
        item.setPen(QPen(Qt.red, 3))

        r = QRectF(QPointF(), rect.size()*0.5)

        item = QGraphicsEllipseItem(r, self.p_item)
        item.setPos(rect.center()-r.center())
        item.setPen(QPen(Qt.blue, 4))

    def print_(self):

        image = QImage(self.gv.viewport().size(), QImage.Format_RGB32)
        image.fill(Qt.transparent)

        painter = QPainter(image)
        self.gv.render(painter)
        painter.end()

        image.save("output.png")

    def showEvent(self, event):
        QWidget.showEvent(self, event)
        self.gv.fitInView(self.scene.sceneRect())


if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

Another example:

import sys

from PyQt4.QtCore import *
from PyQt4.QtGui import * 


class Widget(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        self.btn = QPushButton("Add Line")

        self.gv = QGraphicsView()
        self.scene = QGraphicsScene(self)
        self.gv.setScene(self.scene) 
        self.gv.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform)

        lay = QHBoxLayout(self)
        lay.addWidget(self.btn)
        lay.addWidget(self.gv)

        self.p_item = self.scene.addPixmap(QPixmap("lena.png"))
        self.btn.clicked.connect(self.add_line)

    def add_line(self):
        p1 = self.p_item.boundingRect().topLeft()
        p2 = self.p_item.boundingRect().center()
        line = QGraphicsLineItem(QLineF(p1, p2), self.p_item)
        line.setPen(QPen(Qt.red, 5))
        line.setFlag(QGraphicsItem.ItemIsMovable, True)
        line.setFlag(QGraphicsItem.ItemIsSelectable, True)
        self.gv.fitInView(self.scene.sceneRect())


if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • Thanks very much..I was looking for something very similar - https://stackoverflow.com/questions/8993842/pyqt-drawing-on-an-exsiting-widget-of-gui and it works. I believe u have contributed for this post as well.. – user1050619 Jun 14 '18 at 20:37
  • @eyylanesc: Is there a way for me to have a widget on the left side(right side image) and then I click the widget a line gets generated and dropped at the place where I click...Also, we should be able to resize the line. – user1050619 Jun 14 '18 at 20:42
  • @user1050619 I have added an example, press the button, then press on the line and you can move it by dragging it. – eyllanesc Jun 14 '18 at 21:32
  • @eyylansesc:- Is there a way for me to resize this line in pyqt? Also, is there a way email or number to contact you? – user1050619 Jun 15 '18 at 15:27