本文共 5256 字,大约阅读时间需要 17 分钟。
在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来判断是否按下了左键,必须使用该函数来判断按下鼠标的按键。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函数执行了很多次,每执行一次就会绘制一个矩形,拖动速度越快,重影越少。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/