Призрачные изображения появляются при рисовании прямоугольника с технологией двойной буферизации в PyQt5 - PullRequest
0 голосов
/ 12 декабря 2018

Вот мой код:

import sys
from PyQt5.QtCore import Qt, QPoint
from PyQt5.QtGui import QPainter, QPixmap
from PyQt5.QtWidgets import QApplication, QWidget


class Demo(QWidget):
    def __init__(self):
        super(Demo, self).__init__()
        self.resize(600, 600)

        self.pix = QPixmap(600, 600)
        self.pix.fill(Qt.white)

        self.begin_point = QPoint()
        self.end_point = QPoint()

    def paintEvent(self, QPaintEvent):
        painter = QPainter(self)

        x = self.begin_point.x()
        y = self.begin_point.y()
        w = self.end_point.x()-x
        h = self.end_point.y()-y
        painter2 = QPainter(self.pix)       # paint on a QPixmap first
        painter2.drawRect(x, y, w, h)
        painter.drawPixmap(0, 0, self.pix)  # then pain on the widget

    def mousePressEvent(self, QMouseEvent):
        if QMouseEvent.button() == Qt.LeftButton:
            self.begin_point = QMouseEvent.pos()
            self.end_point = self.begin_point

    def mouseMoveEvent(self, QMouseEvent):
        if QMouseEvent.buttons() == Qt.LeftButton:
            self.end_point = QMouseEvent.pos()
            self.update()


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

Чем медленнее я двигаюсь, тем больше призрачных изображений прямоугольника получаю (левое - медленнее).

enter image description here

Сначала я надеюсь, что мой код показывает правильное понимание технологии двойной буферизации.Пожалуйста, укажите это, если нет.

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

1 Ответ

0 голосов
/ 12 декабря 2018

В этих случаях необходимо иметь 2 типа данных, которые хранят различные типы информации: постоянную и временную информацию.В случае перманента, он должен быть прямоугольником после отпускания мыши, сохраняя его в QPixmap, а временный должен быть нарисован при перетаскивании мыши.

import sys
from PyQt5 import QtCore, QtGui, QtWidgets

class Demo(QtWidgets.QWidget):
    def __init__(self):
        super(Demo, self).__init__()
        self.resize(600, 600)

        self.pix = QtGui.QPixmap(600, 600)
        self.pix.fill(QtCore.Qt.white)
        self.begin_point, self.end_point = QtCore.QPoint(), QtCore.QPoint()

    def paintEvent(self, QPaintEvent):
        painter = QtGui.QPainter(self)
        painter.drawPixmap(QtCore.QPoint(), self.pix)

        if not self.begin_point.isNull() and not self.end_point.isNull():
            r = QtCore.QRect(self.begin_point, self.end_point)
            painter.drawRect(r.normalized())

    def mousePressEvent(self, event):
        if event.button() & QtCore.Qt.LeftButton:
            self.begin_point = event.pos()
            self.end_point = self.begin_point
            self.update()

    def mouseMoveEvent(self, event):
        if event.buttons() & QtCore.Qt.LeftButton:
            self.end_point = event.pos()
            self.update()

    def mouseReleaseEvent(self, event):
        if event.button() & QtCore.Qt.LeftButton:
            r = QtCore.QRect(self.begin_point, self.end_point)
            painter = QtGui.QPainter(self.pix)
            painter.drawRect(r.normalized())
            self.begin_point = self.end_point = QtCore.QPoint() 
            self.update()

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...