博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PyQt5之绘图
阅读量:3959 次
发布时间:2019-05-24

本文共 5256 字,大约阅读时间需要 17 分钟。

PyQt5之绘图

在PyQt中常用的图像类有4个,即QPixmap、QImage、QPicture和QBitmap。

  • QPixmap是专门为绘图而设计的,在绘制图片时需要使用QPixmap;
  • QImage提供了一个与硬件无关的图像表示函数,可以用于图片的像素级访问;
  • QPicture是一个绘图设备类,它继承自QPainter类,可以使用QPainter的begin()函数在QPicture上绘图,使用end()函数结束绘图,使用QPicture的save()函数将QPainter所使用过的绘图指令保存到文件中;
  • QBitmap是一个继承自QPixmap的简单类,它提供了1bit深度的二值图像的类,QBitmap提供的单色图像可以用来制作游标(QCursor)或者笔刷(QBrush)。

一、简单绘图

import sysfrom PyQt5 import QtCorefrom PyQt5.QtWidgets import *from PyQt5.QtGui import *from PyQt5.QtCore import *class Demo(QWidget):    def __init__(self):        super().__init__()        self.setWindowTitle('简单绘图')        self.pix = QPixmap()        self.lastPoint = QPoint()        self.endPoint = QPoint()        self.initUI()    def initUI(self):        self.resize(600, 500)        self.pix = QPixmap(600, 500)  # 设置画布大小        self.pix.fill(Qt.white)  # 设置画布背景颜色为白色    # 绘图    def paintEvent(self, event):        p = QPainter(self.pix)        p.drawLine(self.lastPoint, self.endPoint)  # 根据鼠标指针前后两个位置绘制直线        self.lastPoint = self.endPoint  # 让前一个坐标值等于后一个坐标值,就能画出连续的线        painter = QPainter(self)        painter.drawPixmap(0, 0, self.pix)    #当鼠标左键按下时触发该函数    def mousePressEvent(self, event):        if event.button() == Qt.LeftButton:            self.lastPoint = event.pos()            self.endPoint = self.lastPoint    #当鼠标左键移动时触发该函数    def mouseMoveEvent(self, event):        if event.buttons() and Qt.LeftButton:            self.endPoint = event.pos()            self.update()#调用paintEvent函数,重新绘制    #当鼠标左键释放时触发该函数    def mouseReleaseEvent(self, event):        if event.button() == Qt.LeftButton:            self.endPoint = event.pos()            self.update()  # 调用paintEvent函数,重新绘制if __name__ == "__main__":    app = QApplication(sys.argv)    form = Demo()    form.show()    sys.exit(app.exec_())

运行效果如下:

在这里插入图片描述

注:在重构mouseMoveEvent函数时,buttons()函数可以获取鼠标指针移动过程中按下的所有按键,然后用Qt.LeftButton来判断是否按下了左键,必须使用该函数来判断按下鼠标的按键。

二、双缓冲绘图

  1. 绘制矩形,出现重影:
import sysfrom PyQt5 import QtCorefrom PyQt5.QtWidgets import *from PyQt5.QtGui import *from PyQt5.QtCore import *class Demo(QWidget):    def __init__(self):        super().__init__()        self.setWindowTitle('绘制矩形,出现重影')        self.pix = QPixmap()        self.lastPoint = QPoint()        self.endPoint = QPoint()        self.initUI()    def initUI(self):        self.resize(600, 500)        self.pix = QPixmap(600, 500)  # 设置画布大小        self.pix.fill(Qt.white)  # 设置画布背景颜色为白色    # 绘图    def paintEvent(self, event):        p = QPainter(self.pix)        painter = QPainter(self)        x = self.lastPoint.x()        y = self.lastPoint.y()        w = self.endPoint.x()-x        h = self.endPoint.y()-y        p.drawRect(x,y,w,h)        painter.drawPixmap(0, 0, self.pix)    #当鼠标左键按下时触发该函数    def mousePressEvent(self, event):        if event.button() == Qt.LeftButton:            self.lastPoint = event.pos()            self.endPoint = self.lastPoint    #当鼠标左键移动时触发该函数    def mouseMoveEvent(self, event):        if event.buttons() and Qt.LeftButton:            self.endPoint = event.pos()            self.update()#调用paintEvent函数,重新绘制    #当鼠标左键释放时触发该函数    def mouseReleaseEvent(self, event):        if event.button() == Qt.LeftButton:            self.endPoint = event.pos()            self.update()  # 调用paintEvent函数,重新绘制if __name__ == "__main__":    app = QApplication(sys.argv)    form = Demo()    form.show()    sys.exit(app.exec_())

运行效果如下:

在这里插入图片描述

注:其实,在拖动鼠标的过程中屏幕已经刷新了很多次,即paintEvent函数执行了很多次,每执行一次就会绘制一个矩形,拖动速度越快,重影越少。

  1. 使用双缓冲技术绘制矩形,避免出现重影:
import sysfrom PyQt5 import QtCorefrom PyQt5.QtWidgets import *from PyQt5.QtGui import *from PyQt5.QtCore import *class Demo(QWidget):    def __init__(self):        super().__init__()        self.setWindowTitle('使用双缓冲技术绘制矩形,避免出现重影')        self.pix = QPixmap()        self.lastPoint = QPoint()        self.endPoint = QPoint()        self.temPix = QPixmap()#辅助画布        self.isDrawing = False  #标志是否正在绘图        self.initUI()    def initUI(self):        self.resize(600, 500)        self.pix = QPixmap(600, 500)  # 设置画布大小        self.pix.fill(Qt.white)  # 设置画布背景颜色为白色    # 绘图    def paintEvent(self, event):        painter = QPainter(self)        x = self.lastPoint.x()        y = self.lastPoint.y()        w = self.endPoint.x()-x        h = self.endPoint.y()-y        #如果正在绘图,就在辅助画布上绘制        if self.isDrawing:            self.temPix = self.pix  #将以前pix中的内容复制到辅助画布中,保证以前的内容不消失            p = QPainter(self.temPix)            p.drawRect(x,y,w,h)            painter.drawPixmap(0, 0, self.pix)        else:            p = QPainter(self.pix)            p.drawRect(x, y, w, h)            painter.drawPixmap(0, 0, self.pix)    #当鼠标左键按下时触发该函数    def mousePressEvent(self, event):        if event.button() == Qt.LeftButton:            self.lastPoint = event.pos()            self.endPoint = self.lastPoint            self.isDrawing = True    #当鼠标左键释放时触发该函数    def mouseReleaseEvent(self, event):        if event.button() == Qt.LeftButton:            self.endPoint = event.pos()            self.update()  # 调用paintEvent函数,重新绘制            self.isDrawing = Falseif __name__ == "__main__":    app = QApplication(sys.argv)    form = Demo()    form.show()    sys.exit(app.exec_())

运行效果如下:

在这里插入图片描述

双缓冲技术总结:

在这个例子中,要实现使用鼠标在界面上绘制一个任意大小的矩形而不出现重影,需要两个画布,其中一个作为临时缓冲区。为了在绘制时不出现重影,而且保证以前绘制的内容不消失,那么每一次绘制都是在原来的图形上进行的,所以需要绘制在辅助画布之前,先将pix的内容复制到辅助画布上。

转载地址:http://qtozi.baihongyu.com/

你可能感兴趣的文章