PyQt. QPainter. paintEvent

Я хочу чтобы при при перемещении мыши, в окне проводилась линия на том месте, где был проведён указатель мыши. Для этого я использовал mouseMoveEvent.

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *

class Example(QMainWindow):
    def __init__(self):
        super().__init__()
        self.show()
        self.pen = QPen()
        self.pen.setColor(Qt.green)
    def paintEvent(self, QPaintEvent):
        self.qp = QPainter(self)
        self.qp.setPen(self.pen)
    def mouseMoveEvent(self, event):
        r = event.pos()
        self.qp.drawPoint(r)
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

Следующий код выдаёт ошибку:

QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?

Как исправить?


Ответы (1 шт):

Автор решения: gil9red

Я добавил в комментарии пояснения:

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *

class Example(QMainWindow):
    def __init__(self):
        super().__init__()

        self.pen = QPen()
        self.pen.setColor(Qt.green)
        self.pen.setWidth(20)  # Больше размер, чтобы точка была заметна

        self.pos_points = []         # Переменная для рисования точек
        self.setMouseTracking(True)  # Флаг, чтобы mouseMoveEvent срабатывал без нажатия мышки

    def paintEvent(self, QPaintEvent):
        if not self.pos_points:  # Рисуем если есть данные для этого
            return

        p = QPainter(self)
        p.setPen(self.pen)

        # Рисование на виджете лучше делать в paintEvent
        for pos in self.pos_points:
            p.drawPoint(pos)

    def mouseMoveEvent(self, event):
        self.pos_points.append(event.pos())  # Сохранение данных для рисования
        self.update()                        # Вызов события перерисовки виджета


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

PS.

Если любопытно, то есть более полный пример рисования с несколькими точками разом, да и событий обработки больше: https://github.com/gil9red/SimplePyScripts/blob/8ba59f942ed6a939cc3626b536cae483c682bbac/qt__pyqt__pyside__pyqode/pyqt5_paintEvent_example.py#L49

→ Ссылка