Here is an example code:

class ExampleDraw(QWidget): def __init__(self): super().__init__() self.point = {'x': 0, 'y': 0} def mousePressEvent(self, QMouseEvent): self.point['x'] = QMouseEvent.pos().x() self.point['y'] = QMouseEvent.pos().y() self.update() def paintEvent(self, QPaintEvent): paint = QPainter(self) paint.setBrush(QColor(50, 200, 50, 255)) paint.drawRect(self.point['x'], self.point['y'], 50, 50) 

The problem is that when a new rectangle is drawn and the old one disappears, i.e. As far as I understand it, before drawing, the window field is cleared, and the entire window is redrawn.

How to make sure that the field is not cleared, but only those areas are drawn in which a new figure should be drawn, if possible?

    1 answer 1

    As an option:

     import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import * class Instruction: def paint(self, painter): raise NotImplementedError() class LineInstruction(Instruction): def __init__(self, e): self._e = e def paint(self, painter): painter.setBrush(QColor(50, 200, 50, 255)) painter.drawRect(self._e) class ContextTest: instructions = [] class ExampleDraw(QWidget): def __init__(self): super().__init__() def mousePressEvent(self, event): e = QRect(event.pos().x(), event.pos().y(), 50, 50) instruction = LineInstruction(e) ContextTest.instructions.append(instruction) self.update() def paintEvent(self, QPaintEvent): super().paintEvent(QPaintEvent) qp = QPainter(self) for instruction in ContextTest.instructions: instruction.paint(qp) if __name__ == '__main__': app = QApplication(sys.argv) w = ExampleDraw() w.show() sys.exit(app.exec_()) 

    enter image description here

    Option SECOND:

     import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import * class MainGui(QWidget): def __init__(self): super().__init__() self.resize(600, 400) self.init_UI() def init_UI(self): self.pixmap = QPixmap(600, 400) self.pixmap.fill(QColor(239, 239, 239, 180)) self.label = QLabel(self) self.label.setPixmap(self.pixmap) self.label.mousePressEvent = self.get_pos def drawPoints(self, pos): pen = QPen(QColor(50, 200, 50, 170), 50) qp = QPainter() qp.begin(self.label.pixmap()) qp.setPen(pen) qp.drawPoint(pos.x(), pos.y()) self.label.update() def get_pos(self, event): X = event.pos().x() y = event.pos().y() self.drawPoints(event.pos()) if __name__ == '__main__': app = QApplication(sys.argv) ex = MainGui() ex.show() sys.exit(app.exec_()) 

    enter image description here

    • No, this option will not work. In my application, this is done and when you need to draw 2000+ rectangles when traversing a loop, you notice a drop in performance. That's because I would like the same as in Javascript canvas.clearRect to clean the area, if necessary, but it is better not to clean, those places that, in general, do not need to be updated. Because of the fact that updating the color of one small area, I have to redraw everything (and this is a passage through an array of 2000+ objects). - Sonic Myst
    • I added another example, try it. - S. Nick