Draw a rectangle over an image
-
This is my try (source: https://stackoverflow.com/questions/61034583/drawing-a-circle-on-a-qwidget-python-gui and https://codeloop.org/pyqt5-drawing-rectangle-with-qpainter-class/). I cannot display the image and then above the image the green transparent rectangle...It depicts only the green rectangle and nothing behind...Why?
from PyQt5 import QtGui import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import * class Canvas(QWidget): def __init__(self, photo, *args, **kwargs): super().__init__(*args, **kwargs) self.image = QImage(photo) self.setFixedSize(self.image.width(), self.image.height()) self.pressed = self.moving = False self.revisions = [] self.title = "PyQt5 Drawing Rectangle" self.top = 100 self.left = 100 self.width = 680 self.height = 500 self.InitWindow() def InitWindow(self): self.setWindowIcon(QtGui.QIcon("icon.png")) self.setWindowTitle(self.title) self.setGeometry(self.top, self.left, self.width, self.height) self.show() def paintEvent(self, e): painter = QPainter(self) painter.setPen(QPen(Qt.green, 5, Qt.SolidLine)) painter.setBrush(QBrush(Qt.transparent)) painter.drawRect(100, 150, 400,200) class MainWindow(QMainWindow): def __init__(self): super().__init__() w = QWidget() self.setCentralWidget(w) canvas = Canvas('image3.png') grid = QGridLayout(w) grid.addWidget(canvas) if __name__ == '__main__': app = QApplication(sys.argv) gui = MainWindow() gui.show() sys.exit(app.exec_())
-
Because your are doing nothing with the image beside loading it and you are painting your rectangle in your widget and not on your image.
-
Because your are doing nothing with the image beside loading it and you are painting your rectangle in your widget and not on your image.
@SGaist Ok, what to add/fix in the code? Thanks...
-
Paint the image before the rectangle.
-
I have added this command:
painter.drawImage(photo)
under:
painter = QPainter(self)
Nothing works...I don't see neither the photo, nor the rectangle... Any idea?
-
I did some other tests, nothing...
-
Except that photo is passed only in your
__init__
method.Please provide your code rather than lines without context stating that it does not work.
-
@SGaist Yes, sorry! Here it does not show anything... (source: https://stackoverflow.com/questions/61034583/drawing-a-circle-on-a-qwidget-python-gui and https://codeloop.org/pyqt5-drawing-rectangle-with-qpainter-class/)
from PyQt5 import QtGui import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import * class Canvas(QWidget): def __init__(self, photo, *args, **kwargs): super().__init__(*args, **kwargs) self.image = QImage(photo) self.setFixedSize(self.image.width(), self.image.height()) self.pressed = self.moving = False self.revisions = [] self.title = "PyQt5 Drawing Rectangle" self.top = 100 self.left = 100 self.width = 680 self.height = 500 self.InitWindow() def InitWindow(self): self.setWindowIcon(QtGui.QIcon("icon.png")) self.setWindowTitle(self.title) self.setGeometry(self.top, self.left, self.width, self.height) self.show() def paintEvent(self, e): painter = QPainter(self) painter.drawImage(photo) painter.setPen(QPen(Qt.green, 5, Qt.SolidLine)) painter.setBrush(QBrush(Qt.transparent)) painter.drawRect(100, 150, 400,200) class MainWindow(QMainWindow): def __init__(self): super().__init__() w = QWidget() self.setCentralWidget(w) canvas = Canvas('image3.png') grid = QGridLayout(w) grid.addWidget(canvas) if __name__ == '__main__': app = QApplication(sys.argv) gui = MainWindow() gui.show() sys.exit(app.exec_())
-
And that code runs without triggering an exception ?
"photo" is unknown in your paintEvent. You should draw "self.image". -
And that code runs without triggering an exception ?
"photo" is unknown in your paintEvent. You should draw "self.image".@SGaist If you mean: "painter.drawImage(self.image)" I see neither the image nor the rectangle and many errors...
-
@SGaist If you mean: "painter.drawImage(self.image)" I see neither the image nor the rectangle and many errors...
@john_hobbyist said in Draw a rectangle over an image:
many errors
Would be nice if you would let us know what errors...
-
@jsulm Yes, of course! The code is this (for source see my previous messages...):
from PyQt5 import QtGui import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import * class Canvas(QWidget): def __init__(self, photo, *args, **kwargs): super().__init__(*args, **kwargs) self.image = QImage(photo) self.setFixedSize(self.image.width(), self.image.height()) self.pressed = self.moving = False self.revisions = [] self.title = "PyQt5 Drawing Rectangle" self.top = 100 self.left = 100 self.width = 680 self.height = 500 self.InitWindow() def InitWindow(self): self.setWindowIcon(QtGui.QIcon("icon.png")) self.setWindowTitle(self.title) self.setGeometry(self.top, self.left, self.width, self.height) self.show() def paintEvent(self, e): painter = QPainter(self) painter.drawImage(self.image) painter.setPen(QPen(Qt.green, 5, Qt.SolidLine)) painter.setBrush(QBrush(Qt.transparent)) painter.drawRect(100, 150, 400,200) class MainWindow(QMainWindow): def __init__(self): super().__init__() w = QWidget() self.setCentralWidget(w) canvas = Canvas('image3.png') grid = QGridLayout(w) grid.addWidget(canvas) if __name__ == '__main__': app = QApplication(sys.argv) gui = MainWindow() gui.show() sys.exit(app.exec_())
The errors are these:
Traceback (most recent call last): File "draw_fixed_rectangle_with_image.py", line 32, in paintEvent painter.drawImage(self.image) TypeError: arguments did not match any overloaded call: drawImage(self, QRectF, QImage): argument 1 has unexpected type 'QImage' drawImage(self, QRect, QImage): argument 1 has unexpected type 'QImage' drawImage(self, Union[QPointF, QPoint], QImage): argument 1 has unexpected type 'QImage' drawImage(self, QPoint, QImage): argument 1 has unexpected type 'QImage' drawImage(self, int, int, QImage, sx: int = 0, sy: int = 0, sw: int = -1, sh: int = -1, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' drawImage(self, QRectF, QImage, QRectF, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' drawImage(self, QRect, QImage, QRect, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' drawImage(self, Union[QPointF, QPoint], QImage, QRectF, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' drawImage(self, QPoint, QImage, QRect, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it? Traceback (most recent call last): File "draw_fixed_rectangle_with_image.py", line 32, in paintEvent painter.drawImage(self.image) TypeError: arguments did not match any overloaded call: drawImage(self, QRectF, QImage): argument 1 has unexpected type 'QImage' drawImage(self, QRect, QImage): argument 1 has unexpected type 'QImage' drawImage(self, Union[QPointF, QPoint], QImage): argument 1 has unexpected type 'QImage' drawImage(self, QPoint, QImage): argument 1 has unexpected type 'QImage' drawImage(self, int, int, QImage, sx: int = 0, sy: int = 0, sw: int = -1, sh: int = -1, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' drawImage(self, QRectF, QImage, QRectF, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' drawImage(self, QRect, QImage, QRect, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' drawImage(self, Union[QPointF, QPoint], QImage, QRectF, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' drawImage(self, QPoint, QImage, QRect, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' Traceback (most recent call last): File "draw_fixed_rectangle_with_image.py", line 32, in paintEvent painter.drawImage(self.image) TypeError: arguments did not match any overloaded call: drawImage(self, QRectF, QImage): argument 1 has unexpected type 'QImage' drawImage(self, QRect, QImage): argument 1 has unexpected type 'QImage' drawImage(self, Union[QPointF, QPoint], QImage): argument 1 has unexpected type 'QImage' drawImage(self, QPoint, QImage): argument 1 has unexpected type 'QImage' drawImage(self, int, int, QImage, sx: int = 0, sy: int = 0, sw: int = -1, sh: int = -1, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' drawImage(self, QRectF, QImage, QRectF, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' drawImage(self, QRect, QImage, QRect, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' drawImage(self, Union[QPointF, QPoint], QImage, QRectF, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' drawImage(self, QPoint, QImage, QRect, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it? QPaintDevice: Cannot destroy paint device that is being painted
-
@jsulm Yes, of course! The code is this (for source see my previous messages...):
from PyQt5 import QtGui import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import * class Canvas(QWidget): def __init__(self, photo, *args, **kwargs): super().__init__(*args, **kwargs) self.image = QImage(photo) self.setFixedSize(self.image.width(), self.image.height()) self.pressed = self.moving = False self.revisions = [] self.title = "PyQt5 Drawing Rectangle" self.top = 100 self.left = 100 self.width = 680 self.height = 500 self.InitWindow() def InitWindow(self): self.setWindowIcon(QtGui.QIcon("icon.png")) self.setWindowTitle(self.title) self.setGeometry(self.top, self.left, self.width, self.height) self.show() def paintEvent(self, e): painter = QPainter(self) painter.drawImage(self.image) painter.setPen(QPen(Qt.green, 5, Qt.SolidLine)) painter.setBrush(QBrush(Qt.transparent)) painter.drawRect(100, 150, 400,200) class MainWindow(QMainWindow): def __init__(self): super().__init__() w = QWidget() self.setCentralWidget(w) canvas = Canvas('image3.png') grid = QGridLayout(w) grid.addWidget(canvas) if __name__ == '__main__': app = QApplication(sys.argv) gui = MainWindow() gui.show() sys.exit(app.exec_())
The errors are these:
Traceback (most recent call last): File "draw_fixed_rectangle_with_image.py", line 32, in paintEvent painter.drawImage(self.image) TypeError: arguments did not match any overloaded call: drawImage(self, QRectF, QImage): argument 1 has unexpected type 'QImage' drawImage(self, QRect, QImage): argument 1 has unexpected type 'QImage' drawImage(self, Union[QPointF, QPoint], QImage): argument 1 has unexpected type 'QImage' drawImage(self, QPoint, QImage): argument 1 has unexpected type 'QImage' drawImage(self, int, int, QImage, sx: int = 0, sy: int = 0, sw: int = -1, sh: int = -1, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' drawImage(self, QRectF, QImage, QRectF, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' drawImage(self, QRect, QImage, QRect, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' drawImage(self, Union[QPointF, QPoint], QImage, QRectF, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' drawImage(self, QPoint, QImage, QRect, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it? Traceback (most recent call last): File "draw_fixed_rectangle_with_image.py", line 32, in paintEvent painter.drawImage(self.image) TypeError: arguments did not match any overloaded call: drawImage(self, QRectF, QImage): argument 1 has unexpected type 'QImage' drawImage(self, QRect, QImage): argument 1 has unexpected type 'QImage' drawImage(self, Union[QPointF, QPoint], QImage): argument 1 has unexpected type 'QImage' drawImage(self, QPoint, QImage): argument 1 has unexpected type 'QImage' drawImage(self, int, int, QImage, sx: int = 0, sy: int = 0, sw: int = -1, sh: int = -1, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' drawImage(self, QRectF, QImage, QRectF, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' drawImage(self, QRect, QImage, QRect, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' drawImage(self, Union[QPointF, QPoint], QImage, QRectF, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' drawImage(self, QPoint, QImage, QRect, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' Traceback (most recent call last): File "draw_fixed_rectangle_with_image.py", line 32, in paintEvent painter.drawImage(self.image) TypeError: arguments did not match any overloaded call: drawImage(self, QRectF, QImage): argument 1 has unexpected type 'QImage' drawImage(self, QRect, QImage): argument 1 has unexpected type 'QImage' drawImage(self, Union[QPointF, QPoint], QImage): argument 1 has unexpected type 'QImage' drawImage(self, QPoint, QImage): argument 1 has unexpected type 'QImage' drawImage(self, int, int, QImage, sx: int = 0, sy: int = 0, sw: int = -1, sh: int = -1, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' drawImage(self, QRectF, QImage, QRectF, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' drawImage(self, QRect, QImage, QRect, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' drawImage(self, Union[QPointF, QPoint], QImage, QRectF, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' drawImage(self, QPoint, QImage, QRect, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'QImage' QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it? QPaintDevice: Cannot destroy paint device that is being painted
@john_hobbyist Please take a look at documentation: https://doc.qt.io/qt-5/qpainter.html
What are drawImage() parameters? And what do you pass to it? It is quite apparent what you are doing wrong even from the error message itself:drawImage(self, QRectF, QImage): argument 1 has unexpected type 'QImage'
-
The error is pretty explicit. There's no overload of drawImage that takes only a QImage as parameter. It's always the second one.
-
Thank you all for your time and your significant comments! I mark it as "Solved!"
-
Just a small question, in case I want to depict the rectangle in an image displayed in this application: https://github.com/Axel-Erfurt/OrthoViewLite/blob/main/OrthoViewLite.py how can I achieve that? Where should I place the above code?
-
What is this rectangle supposed to do in your application ? Depending on that, it would be simpler to use a QRubberBand.
-
What is this rectangle supposed to do in your application ? Depending on that, it would be simpler to use a QRubberBand.
@SGaist The rectangles are placed there in specific positions and with specific dimensions....They are programmed from the python code. I don't draw rectangles with the mouse...
-
Any idea?
-
Well, it would be simpler to draw your rectangle directly on the QImage where you create them.