写点什么

Python Qt GUI 设计:QPainter、QPen、QBrush 和 QPixmap 窗口绘图类(基础篇—17)

  • 2021 年 11 月 26 日
  • 本文字数:4023 字

    阅读完需:约 13 分钟

Python Qt GUI设计:QPainter、QPen、QBrush和QPixmap窗口绘图类(基础篇—17)

本篇博文主要介绍如何实现在窗口中绘图,在 PyQt5 中,一般可以通过 QPainter、QPen、QBrush 和 QPixmap 这四个类来实现绘图功能。其中,QPixmap 的作用是加载并呈现本地图像,而图像的呈现本质上也是通过绘图方式实现的。

1、QPainter 绘图类

QPainter 类在 QWidget(控件)上执行绘图操作,它是一个绘制工具,为大部分图形界面提供了高度优化的函数,使 QPainter 类可以绘制从简单的直线到复杂的饼图等。

绘制操作在 QWidget.paintEvent()中完成,绘制方法必须放在 QtGui.QPainter 对象的 begin()和 end()之间 QPainter 类在控件或其他绘图设备上执行较低级别的图形绘制功能,并通过如下表所示的方法进行绘制:

还可以设置画笔风格(PenStyle),这是一个枚举类,可以由 QPainter 类绘制。画笔风格如下表所示:

画笔效果如下所示:

来看看 QPainter 绘图类的示例,效果如下所示:

示例中,首先定义了待绘制的文字,代码如下所示:

self.text = '公众号:美男子玩编程'
复制代码

然后,定义了一个绘制事件,所有的绘制操作都发生在此事件内。绘制事件代码如下所示:

	def paintEvent(self,event):		painter = QPainter(self)        		painter.begin(self)        # 自定义的绘画方法		self.drawText(event, painter)		painter.end()
复制代码

QtGui.QPainter 类负责所有低级别的绘制,所有的绘制方法都要放在 begin()和 end()之间。这个例子放置的是自定义的 drawText()方法。自定义的绘制方法代码如下所示:

def drawText(self, event, qp):    # 设置笔的颜色  qp.setPen( QColor(168, 34, 3) )    # 设置字体  qp.setFont( QFont('SimSun', 20))    # 画出文本  qp.drawText(event.rect(), Qt.AlignCenter, self.text)
复制代码


实现代码如下所示:

import sysfrom PyQt5.QtWidgets import QApplication  ,QWidget from PyQt5.QtGui import QPainter ,QColor ,QFontfrom PyQt5.QtCore import Qt  class Drawing(QWidget):	def __init__(self,parent=None):		super(Drawing,self).__init__(parent)		self.setWindowTitle("在窗体中绘画出文字例子") 		self.resize(300, 200)        		self.text = '公众号:美男子玩编程'         	def paintEvent(self,event):		painter = QPainter(self)        		painter.begin(self)        # 自定义的绘画方法		self.drawText(event, painter)		painter.end() 	def drawText(self, event, qp):        # 设置笔的颜色		qp.setPen( QColor(168, 34, 3) )        # 设置字体		qp.setFont( QFont('SimSun', 20))        # 画出文本		qp.drawText(event.rect(), Qt.AlignCenter, self.text)		if __name__ == "__main__":  	app = QApplication(sys.argv) 	demo = Drawing()	demo.show()	sys.exit(app.exec_())
复制代码

QPainter 绘制文字,实质上文字在屏幕上的显示是由一个个点(point)组成的,来看看 QPainter 如何绘制点。效果如下所示:

示例中,在窗口的工作区绘制正弦函数图形,周期是[-100,100]。画笔设置为红色,使用预定义的 Qt.red 颜色。每次调整窗口大小时,都会生成一个绘图事件。使用 size()方法得到窗口的当前大小,在新的窗口中随机分布工作区中的点。最后使用 drawPoint()方法绘制一个个点。

实现代码如下所示:

import sys, mathfrom PyQt5.QtWidgets import *  from PyQt5.QtGui import *from PyQt5.QtCore import Qt  class Drawing(QWidget):	def __init__(self, parent=None):		super(Drawing, self).__init__(parent)		self.resize(300, 200)  		self.setWindowTitle("在窗体中画点")          	def paintEvent(self, event):		qp = QPainter()		qp.begin(self)		# 自定义画点方法		self.drawPoints(qp)		qp.end()			def drawPoints(self,  qp):		qp.setPen( Qt.red)		size = self.size()				for i in range(1000):			# [-100, 100]两个周期的正弦函数图像			x = 100 *(-1+2.0*i/1000)+ size.width()/2.0			y = -50 * math.sin((x - size.width()/2.0)*math.pi/50) + size.height()/2.0			qp.drawPoint(x, y) if __name__ == '__main__':	app = QApplication(sys.argv)	demo  = Drawing()	demo.show()	sys.exit(app.exec_())
复制代码

2、QPen 绘图类

QPen(钢笔)是一个基本的图形对象,用于绘制直线、曲线或者给轮廓画出矩形、椭圆形、多边形及其他形状等。

来看看 QPen 绘图类的示例,效果如下所示:

示例中,使用 6 种不同的线条样式绘制了 6 条线,其中前 5 条线使用的是预定义的线条样式。也可以自定义线条样式,最后一条线就是使用自定义的线条样式绘制的。

以下代码创建了一个 QPen 对象。为了能更清晰地看清各线之间的差异,将颜色设置成黑色,宽度设置为 2 像素(px)。Qt.SolidLine 是预定义的线条样式之一。

 pen = QPen(Qt.black, 2, Qt.SolidLine)
复制代码

以下代码自定义了一种线条样式。使用 Qt.customDashLine 创建线条样式,然后调用 setDashPattern()方法使用数字列表定义样式。数字列表的个数必须是偶数,在本例中数字列表是[1,4,5,4],它的个数是 4。在数字列表中,奇数位(数字列表中的第 1,3,5 等位置)代表一段横线,偶数位(数字列表中的第 2,4,6 等位置)代表两段横线之间的空余距离。在数字列表中数字越大,横线和空余距离就越大。本例中数字列表[1,4,5,4]代表的意义是:1 像素宽度的横线,4 像素宽度的空余距离,5 像素宽度的横线,4 像素宽度的空余距离。

 		pen.setStyle(Qt.CustomDashLine)		pen.setDashPattern([1, 4, 5, 4])		qp.setPen(pen)		qp.drawLine(20, 240, 250, 240)
复制代码

实现代码如下所示:

import sys from PyQt5.QtWidgets import *  from PyQt5.QtGui import *from PyQt5.QtCore import Qt  class Drawing(QWidget):	def __init__(self):		super().__init__()		self.initUI() 	def initUI(self):   		self.setGeometry(300, 300, 280, 270)		self.setWindowTitle('钢笔样式例子')         	def paintEvent(self, e): 		qp = QPainter()		qp.begin(self)		self.drawLines(qp)		qp.end() 	def drawLines(self, qp):		pen = QPen(Qt.black, 2, Qt.SolidLine) 		qp.setPen(pen)		qp.drawLine(20, 40, 250, 40) 		pen.setStyle(Qt.DashLine)		qp.setPen(pen)		qp.drawLine(20, 80, 250, 80) 		pen.setStyle(Qt.DashDotLine)		qp.setPen(pen)		qp.drawLine(20, 120, 250, 120) 		pen.setStyle(Qt.DotLine)		qp.setPen(pen)		qp.drawLine(20, 160, 250, 160) 		pen.setStyle(Qt.DashDotDotLine)		qp.setPen(pen)		qp.drawLine(20, 200, 250, 200) 		pen.setStyle(Qt.CustomDashLine)		pen.setDashPattern([1, 4, 5, 4])		qp.setPen(pen)		qp.drawLine(20, 240, 250, 240) if __name__ == '__main__':	app = QApplication(sys.argv)	demo = Drawing()	demo.show()	sys.exit(app.exec_())
复制代码

3、QBrush 绘图类

QBrush(画刷)是一个基本的图形对象,用于填充如矩形、椭圆形或多边形等形状。QBrush 有三种类型:预定义、过渡和纹理图案。

来看看 QBrush 绘图类的示例,效果如下所示:

在这个例子中,在窗口中绘制出 9 种不同背景填充的矩形。定义 QBrush 对象,然后将 QPainter 对象的画刷设置成 QBrush 对象,并通过调用 drawRect()方法绘制矩形。

实现代码如下所示:

import sys from PyQt5.QtWidgets import *  from PyQt5.QtGui import *from PyQt5.QtCore import Qt  class Drawing(QWidget): 	def __init__(self):		super().__init__()  		self.initUI() 	def initUI(self):   		self.setGeometry(300, 300, 365, 280)		self.setWindowTitle('画刷例子')        		self.show() 	def paintEvent(self, e): 		qp = QPainter()		qp.begin(self)		self.drawLines(qp)		qp.end() 	def drawLines(self, qp): 		brush = QBrush(Qt.SolidPattern)		qp.setBrush(brush)		qp.drawRect(10, 15, 90, 60) 		brush = QBrush(Qt.Dense1Pattern)		qp.setBrush(brush)		qp.drawRect(130, 15, 90, 60) 		brush = QBrush(Qt.Dense2Pattern)		qp.setBrush(brush)		qp.drawRect(250, 15, 90, 60) 		brush = QBrush(Qt.Dense3Pattern)		qp.setBrush(brush)		qp.drawRect(10, 105, 90, 60) 		brush = QBrush(Qt.DiagCrossPattern)		qp.setBrush(brush)		qp.drawRect(10, 105, 90, 60) 		brush = QBrush(Qt.Dense5Pattern)		qp.setBrush(brush)		qp.drawRect(130, 105, 90, 60) 		brush = QBrush(Qt.Dense6Pattern)		qp.setBrush(brush)		qp.drawRect(250, 105, 90, 60) 		brush = QBrush(Qt.HorPattern)		qp.setBrush(brush)		qp.drawRect(10, 195, 90, 60) 		brush = QBrush(Qt.VerPattern)		qp.setBrush(brush)		qp.drawRect(130, 195, 90, 60) 		brush = QBrush(Qt.BDiagPattern)		qp.setBrush(brush)		qp.drawRect(250, 195, 90, 60)                         		if __name__ == '__main__':	app = QApplication(sys.argv)	demo = Drawing()	demo.show()	sys.exit(app.exec_())
复制代码

4、QPixmap 绘图类

QPixmap 类用于绘图设备的图像显示,它可以作为一个 QPaintDevice 对象,也可以加载到一个控件中,通常是标签或按钮,用于在标签或按钮上显示图像。

QPixmap 可以读取的图像文件类型有 BMP、GIF、JPG、JPEG、PNG、PBM、PGM、PPM、XBM、XPM 等。

QPixmap 类中的常用方法如下表所示:

示例中,使用 setPixmap()将图像显示在 QLabel 上。实现代码如下所示:

实现代码如下所示:

import sysfrom PyQt5.QtCore import *from PyQt5.QtGui import *from PyQt5.QtWidgets import * if __name__ == '__main__':	app = QApplication(sys.argv)	win = QWidget()	lab1 = QLabel()	lab1.setPixmap(QPixmap("./2.jpg"))	vbox=QVBoxLayout()	vbox.addWidget(lab1)	win.setLayout(vbox)	win.setWindowTitle("QPixmap 例子")	win.show()	sys.exit(app.exec_())
复制代码


发布于: 2021 年 11 月 26 日阅读数: 9
用户头像

【研究方向】物联网、嵌入式、AI、Python 2018.02.09 加入

【公众号】美男子玩编程,关注获取海量资源~

评论

发布
暂无评论
Python Qt GUI设计:QPainter、QPen、QBrush和QPixmap窗口绘图类(基础篇—17)