pyqt5示例_PyQt5双缓冲绘图示例(PyQt5 double buffering drawing)

在使用PyQt5绘制图形的过程中,如果想要避免绘制过程中产生的拖影,就必须使用双缓冲绘图。但是网上的中文资料并没有很好的演示这一点,《PyQt5快速开发与实战》这本书中给出的例子也是残缺的(可以参考GitHub上的代码 https://github.com/cxinping/PyQt5/blob/master/Chapter08/qt08_winDraw03.py)。

废话不多说,下面的代码示例演示了:如何在空白画布上绘制矩形图案,避免拖影且能实时看到矩形。

 import sys
    from PyQt5.QtWidgets import QApplication  ,QWidget 
    from PyQt5.QtGui import   QPainter ,QPixmap
    from PyQt5.QtCore import Qt , QPoint
    
    
    class Winform(QWidget):
        def __init__(self, parent=None):
            super(Winform, self).__init__(parent)
            self.setWindowTitle("双缓冲绘图示意")
            self.resize(600, 500)
            self.pix =  QPixmap(400, 400) # 400*400画布
            self.pix.fill(Qt.white) # 白色填充
            self.temp = QPixmap() # 辅助画布
            self.lastPoint =  QPoint() # 起点
            self.endPoint =  QPoint() # 终点
        
        def paintEvent(self, event):
            """
            重载绘制事件。
            将self.pix中的内容复制到缓存中,在缓存上绘图。
            """
            x = self.lastPoint.x()
            y = self.lastPoint.y()
            w = self.endPoint.x() - x
            h = self.endPoint.y() - y
            
            self.temp = self.pix.copy() # 如果直接赋值,两者的内存是相同的,因此这里需要调用copy。
            pp = QPainter(self.temp)
            pp.drawRect(x,y,w,h)
            painter = QPainter(self)
            painter.drawPixmap(0, 0, self.temp)  
        
        
        def mousePressEvent(self, event):
            """
            按下鼠标左键后,将当前位置存储到起点中。
            """
            if event.button() == Qt.LeftButton :
                self.lastPoint = event.pos()
    	
        
        def mouseMoveEvent(self, event):
            """
            鼠标左键被按下且在滑动中,调用绘图函数,更新画布内容。
            """
            if event.buttons() and Qt.LeftButton: # 这里的写法非常重要
                self.endPoint = event.pos()
                self.update()
        
        def mouseReleaseEvent(self, event):
            """
            松开鼠标左键后,将当前位置存储到终点中;绘制图案,并将缓存中的内容更新到self.pix中。
            """
            self.endPoint = event.pos()
            self.update()
            self.pix = self.temp.copy()
    
    
    if __name__ == "__main__":  
        app = QApplication(sys.argv) 
        form = Winform()
        form.show()
        sys.exit(app.exec_())

在这里需要注意的要点有:

1. 每次绘图前进行复制,将已经绘制好的矩形复制到缓存画布上。这样一来,画布上的内容不受影响,且能够通过缓存画布实时显示当前正在绘制的矩形。(复制过程让缓存画布丢弃了上一次绘制中的矩形,因此也就消除了拖影。)

2. 绘制结束后,即鼠标释放时,将缓存画布上的内容复制到画布上,保证其内容得到更新。

3. 调用copy函数,以便画布和缓存画布的内存是不同的。

4. 在`mouseMoveEvent`中使用` event.buttons() and Qt.LeftButton`做条件判断保证绘制事件可以随鼠标的移动而触发。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值