在PyQt5中使用双缓冲技术绘制矩形时显示鬼图像

时间:2018-12-12 14:53:05

标签: python pyqt pyqt5 pyqtgraph

这是我的代码:

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_())

我移动的速度越慢,我得到的rect的鬼影就越多(左一个慢一些)。 enter image description here

首先,我希望我的代码能正确理解双重缓冲技术。如果没有请指出。

我知道这是由于paintEvent()调用过多所致。我想知道如何正确设置它而不删除mouseMoveEvent(),因为我希望用户在绘制它时始终看到矩形。

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

在这些情况下,将具有两种存储不同类型信息的数据类型:永久性信息和临时性信息。对于永久性对象,它必须是释放鼠标后的矩形,并将其保存在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