(二)PyQt5绘图技术
使用图形分析数据,不仅简单明了,而且清晰可见,它是项目开发中的一项必备功能,那么,在PyQt5中如何实现图形的绘制呢?答案就是QPainter类。使用QPainter类可以绘制各种图形,从简单的点、直线,到复杂的饼图、柱状图等。
本节介绍PyQt5中绘图的基础知识,其中包括QPainter绘图基础类、QPen画笔对象、QBrush画刷对象和QFont字体对象;然后讲解了如何在PyQt5程序中绘制文本与图像。绘图技术在PyQt5程序开发中的应用比较广泛,需要认真学习掌握。
1. PyQt5绘图基础
绘图是窗口程序设计中非常重要的技术,例如,应用程序需要绘制闪屏图像、背景图像、各种图形形状等。正所谓“一图胜千言” ,使用图像能够更好地表达程序运行结果,进行细致地数据分析与保存等。
QPainter类是PyQt5中的绘图基础类,它可以在QWidget控件上执行绘图操作,具体的绘图操作在QWidget的paintEvent()方法中完成。
创建一个QPainter绘图对象的方法非常简单,代码如下:
from PyQt5.QtGui import QPainter
painter = QPainter(self)
QPainter类中常用的图形绘制方法及说明
示例:使用QPainter绘制图形
创建一个.py文件,导入PyQt5的相应模块,然后分别使用QPainter类的相应方法在PyQt5窗口中绘制椭圆、矩形、直线和文本等图形。
完整代码如下:
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QPainter
from PyQt5.QtCore import Qt
class Demo(QWidget):
def __init__(self, parent=None):
super(Demo, self).__init__(parent)
self.setWindowTitle("QPainter绘制图形") # 设置窗口标题
self.resize(300, 120) # 设置窗口大小
def paintEvent(self, event):
painter = QPainter(self) # 创建绘图对象
painter.setPen(Qt.red) # 设置画笔
painter.drawEllipse(80, 10, 50, 30) # 绘制一个椭圆
painter.drawRect(180, 10, 50, 30) # 绘制一个矩形
painter.drawLine(80, 70, 200, 70) # 绘制直线
painter.drawText(50, 100, "岂能尽如人意,但求无愧我心。")
if __name__ == "__main__":
import sys
app = QApplication(sys.argv) # 创建窗口程序
demo = Demo() # 创建窗口类对象
demo.show() # 显示窗口
sys.exit(app.exec_())
运行效果如下:
2. 设置画笔与画刷
在使用QPainter类绘制图形时,可以使用setPen()方法和setBrsuh()方法对画笔和画刷进行设置,它们的参数分别是一个QPen对象和一个QBrush对象。
1. 设置画笔:QPen
QPen类主要用来设置画笔。
QPen类的常用方法及说明
使用setColor()方法设置画笔颜色时,可以使用QColor对象根据RGB值生成颜色,也可以使用QtCore.Qt模块提供的内置颜色进行设置,如Qt.red表示红色,Qt.green表示绿色等。
示例:展示不同画笔样式
创建一个.py文件,导入PyQt5的相应模块,通过QPen对象的setStyle()方法设置6种不同的画笔样式,并分别以设置的画笔绘制直线。
完整代码如下:
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QPainter, QPen, QColor
from PyQt5.QtCore import Qt
class Demo(QWidget):
def __init__(self, parent=None):
super(Demo, self).__init__(parent)
self.setWindowTitle("画笔的设置") # 设置窗口标题
self.resize(300, 120) # 设置窗口大小
def paintEvent(self, event):
painter = QPainter(self) # 创建绘图对象
pen = QPen() # 创建画笔对象
# 设置第1条直线的画笔
pen.setColor(Qt.red) # 设置画笔颜色为红色
pen.setStyle(Qt.SolidLine) # 设置画笔颜色为正常直线
pen.setWidth(1) # 设置画笔宽度
painter.setPen(pen) # 设置画笔
painter.drawLine(80, 10, 200, 10) # 绘制直线
# 设置第2条直线的画笔
pen.setColor(Qt.blue) # 设置画笔颜色为蓝色
pen.setStyle(Qt.DashLine) # 设置画笔样式为由一些像素分割的短线
pen.setWidth(2) # 设置画笔宽度
painter.setPen(pen) # 设置画笔
painter.drawLine(80, 30, 200, 30) # 绘制直线
# 设置第3条直线的画笔
pen.setColor(Qt.cyan) # 设置画笔颜色为青色
pen.setStyle(Qt.DotLine) # 设置画笔样式为由一些像素分割的点
pen.setWidth(3) # 设置画笔宽度
painter.setPen(pen) # 设置画笔
painter.drawLine(80, 50, 200, 50) # 绘制直线
# 设置第4条直线的画笔
pen.setColor(Qt.green) # 设置画笔颜色为绿色
pen.setStyle(Qt.DashDotLine) # 设置画笔样式为交替出现的短线和点
pen.setWidth(4) # 设置画笔宽度
painter.setPen(pen) # 设置画笔
painter.drawLine(80, 70, 200, 70) # 绘制直线
# 设置第5条直线的画笔
pen.setColor(Qt.black) # 设置画笔颜色为黑色
pen.setStyle(Qt.DashDotDotLine) # 设置画笔样式为交替出现的短线和两个点
pen.setWidth(5) # 设置画笔宽度
painter.setPen(pen) # 设置画笔
painter.drawLine(80, 90, 200, 90) # 绘制直线
# 设置第6条直线的画笔
pen.setColor(QColor(48, 235, 100)) # 自定义画笔颜色
pen.setStyle(Qt.CustomDashLine) # 设置画笔样式为自定义样式
pen.setDashPattern([1, 3, 2, 3]) # 设置自定义的画笔样式
pen.setWidth(6) # 设置画笔宽度
painter.setPen(pen) # 设置画笔
painter.drawLine(80, 110, 200, 110) # 绘制直线
if __name__ == "__main__":
import sys
app = QApplication(sys.argv) # 创建窗口程序
demo = Demo() # 创建窗口类对象
demo.show() # 显示窗口
sys.exit(app.exec_())
运行效果如下:
2. 设置画刷:QBrush
QBrush类主要用于设置画刷,以填充几何图形,如将正方形和圆形填充为其他颜色。
QBrush类的常用方法及说明
示例:展示不同的画刷样式
创建一个.py文件,导入PyQt5的相应模块,通过QBrush对象的setStyle()方法设置18种不同的画刷样式,并分别以设置的画刷对绘制的矩形进行填充,观察它们的不同效果。
完整代码如下:
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import Qt, QPoint
class Demo(QWidget):
def __init__(self, parent=None):
super(Demo, self).__init__(parent)
# self.resize(430, 255) # 设置窗口大小
self.resize(435, 255) # 设置窗口大小
self.setWindowTitle("画刷的设置") # 设置窗口标题
def paintEvent(self, event):
painter = QPainter(self) # 创建绘图对象
brush = QBrush() # 创建画刷对象
# 创建第1列的矩形及标识文字
# 设置第1个矩形的画刷
brush.setColor(Qt.red) # 设置画刷颜色为红色
brush.setStyle(Qt.SolidPattern) # 设置画刷样式为纯色样式
painter.setBrush(brush) # 设置画刷
painter.drawRect(10, 10, 30, 30) # 绘制矩形
painter.drawText(50, 30, "纯色样式") # 绘制标识文本
# 设置第2个矩形的画刷
brush.setColor(Qt.blue) # 设置画刷颜色为蓝色
brush.setStyle(Qt.Dense1Pattern) # 设置画刷样式为密度样式1
painter.setBrush(brush) # 设置画刷
painter.drawRect(10, 50, 30, 30) # 绘制矩形
painter.drawText(50, 70, "密度样式 1") # 绘制标识文本
# 设置第3个矩形和画刷
brush.setColor(Qt.cyan) # 设置画刷颜色为青色
brush.setStyle(Qt.Dense2Pattern) # 设置画刷样式为密度样式2
painter.setBrush(brush) # 设置画刷
painter.drawRect(10, 90, 30, 30) # 绘制矩形
painter.drawText(50, 110, "密度样式 2") # 绘制标识文本
# 设置第4个矩形和画刷
brush.setColor(Qt.blue) # 设置画刷颜色为蓝色
brush.setStyle(Qt.Dense3Pattern) # 设置画刷样式为密度样式3
painter.setBrush(brush) # 设置画刷
painter.drawRect(10, 130, 30, 30) # 绘制矩形
painter.drawText(50, 150, "密度样式 3") #绘制标识文本
# 设置第5个矩形和画刷
brush.setColor(Qt.black) # 设置画刷颜色为黑色
brush.setStyle(Qt.Dense4Pattern) # 设置画刷样式为密度样式4
painter.setBrush(brush) # 设置画刷
painter.drawRect(10, 170, 30, 30) # 绘制矩形
painter.drawText(50, 190, "密度样式 4") # 绘制标识文本
# 设置第6个矩形和画框
brush.setColor(Qt.darkMagenta) # 设置画刷颜色为洋红色
brush.setStyle(Qt.Dense5Pattern) # 设置画刷样式为密度样式5
painter.setBrush(brush) # 设置画刷
painter.drawRect(10, 210, 30, 30) # 绘制矩形
painter.drawText(50, 230, "密度样式 5") # 绘制标识文本
# 创建第2列的矩形及标识文字
# 设置第1个矩形的画刷
brush.setColor(Qt.red) # 设置画刷颜色为红色
brush.setStyle(Qt.Dense6Pattern) # 设置画刷样式为密度样式6
painter.setBrush(brush) # 设置画刷
painter.drawRect(150, 10, 30, 30) # 绘制矩形
painter.drawText(190, 30, "密度样式 6") # 绘制标识文本
# 设置第2个矩形的画刷
brush.setColor(Qt.blue) # 设置画刷颜色
brush.setStyle(Qt.Dense7Pattern) # 设置画刷样式为密度样式7
painter.setBrush(brush) # 设置画刷
painter.drawRect(150, 50, 30, 30) # 绘制矩形
painter.drawText(190, 70, "密度样式 7") # 绘制标识文本
# 设置第3个矩形的画刷
brush.setColor(Qt.cyan) # 设置画刷颜色诶绿色
brush.setStyle(Qt.HorPattern) # 设置画刷样式为水平线样式
painter.setBrush(brush) # 设置画刷
painter.drawRect(150, 90, 30, 30) # 绘制矩形
painter.drawText(190, 110, "水平线样式")
# 设置第4个矩形的画刷
brush.setColor(Qt.green)
brush.setStyle(Qt.VerPattern) # 设置画刷样式为垂直线样式
painter.setBrush(brush)
painter.drawRect(150, 130, 30, 30)
painter.drawText(190, 150, "垂直线样式")
# 设置第5个矩形的画刷
brush.setColor(Qt.black)
brush.setStyle(Qt.CrossPattern)
painter.setBrush(brush)
painter.drawRect(150, 170, 30, 30)
painter.drawText(190, 190, "交叉线样式")
# 设置第6个矩形的画刷
brush.setColor(Qt.darkMagenta)
brush.setStyle(Qt.DiagCrossPattern)
painter.setBrush(brush)
painter.drawRect(150, 210, 30, 30)
painter.drawText(190, 230, "倾斜交叉线样式")
# 设置第3列的矩形和表示文字
# 设置第1个矩形的画刷
brush.setColor(Qt.red)
brush.setStyle(Qt.BDiagPattern)
painter.setBrush(brush)
painter.drawRect(300, 10, 30, 30)
painter.drawText(340, 30, "反斜线样式")
# 设置第2个矩形的画刷
brush.setColor(Qt.blue)
brush.setStyle(Qt.FDiagPattern)
painter.setBrush(brush)
painter.drawRect(300, 50, 30, 30)
painter.drawText(340, 70, "倾斜样式")
# 设置第3个矩形的画刷
# 设置线性渐变区域
linearCradient = QLinearGradient(QPoint(300, 90), QPoint(330, 120))
linearCradient.setColorAt(0, Qt.red) # 设置渐变色1
linearCradient.setColorAt(1, Qt.yellow) # 设置渐变色2
linearbrush = QBrush(linearCradient) # 创建线性渐变画刷
linearbrush.setStyle(Qt.LinearGradientPattern) # 设置画刷样式为线性渐变样式
painter.setBrush(linearbrush) # 设置画刷
painter.drawRect(300, 90, 30, 30) # 绘制矩形
painter.drawText(340, 110, "线性渐变样式")
# 设置第4个矩形的画刷
# 设置锥形渐变区域
conicalGradient = QConicalGradient(315, 145, 0)
# 将要渐变的区域分为6个区域,分别设置颜色
conicalGradient.setColorAt(0, Qt.red)
conicalGradient.setColorAt(0.2, Qt.yellow)
conicalGradient.setColorAt(0.4, Qt.blue)
conicalGradient.setColorAt(0.6, Qt.green)
conicalGradient.setColorAt(0.8, Qt.magenta)
conicalGradient.setColorAt(1.0, Qt.cyan)
conicalbrush = QBrush(conicalGradient) # 创建锥形渐变画刷
conicalbrush.setStyle(Qt.ConicalGradientPattern) # 设置画刷样式为锥形渐变样式
painter.setBrush(conicalbrush) # 设置画刷
painter.drawRect(300, 130, 30, 30) # 绘制矩形
painter.drawText(340, 150, "锥形渐变样式") # 绘制标识文本
# 设置第5个矩形的画刷
# 设置放射渐变区域
radialGradient = QRadialGradient(QPoint(315, 185), 15)
radialGradient.setColorAt(0, Qt.green) # 设置中心点颜色
radialGradient.setColorAt(0.5, Qt.yellow) # 设置内圈颜色
radialGradient.setColorAt(1, Qt.darkMagenta) # 设置外圈颜色
radialbrush = QBrush(radialGradient) # 创建放射渐变画刷
radialbrush.setStyle(Qt.RadialGradientPattern) # 设置画刷样式为放射渐变样式
painter.setBrush(radialbrush) # 设置画刷
painter.drawRect(300, 170, 30, 30) # 绘制矩形
painter.drawText(340, 190, "放射渐变样式") # 绘制标识文本
# 设置第6个矩形的画刷
brush.setStyle(Qt.TexturePattern) # 设置画刷样式为纹理样式
brush.setTexture(QPixmap("./image/test.png")) # 设置作为纹理的图片
painter.setBrush(brush) # 设置画刷
painter.drawRect(300, 210, 30, 30) # 绘制矩形
painter.drawText(340, 230, "纹理样式") # 绘制标识文本
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
demo = Demo()
demo.show()
sys.exit(app.exec_())
运行效果如下:
在设置线性渐变画刷、锥形渐变画刷和放射性渐变画刷时,分别需要使用QLinearGradient类、QConicalGradient类和QRadialGradient类设置渐变的区域,并且他们有一个通用的方法setColorAt(),用来设置渐变的颜色;另外,在设置纹理画刷时,需要使用setTexture()方法或者setTextureImage()方法指定作为纹理的图片。
3. 绘制文本
使用QPainter绘图类可以绘制文本内容,并且在绘制文本之前可以设置使用的字体、大小等。
1. 设置字体:QFont
在PyQt5中使用QFont类封装了字体的大小、样式等属性。
QFont类的常用方法及说明
例如,创建一个QFont字体对象,并对字体进行相应的设置。
font = QFont() # 创建字体对象
font.setFamily("华文行楷") # 设置字体
font.setPointSize(20) # 设置文字大小
font.setBold(True) # 设置粗体
font.setUnderline(True) # 设置下画线
font.setLetterSpacing(QFont.PercentageSpacing, 150) # 设置字间距
2. 绘制文本
QPainter类提供了drawText()方法,用来在窗口中绘制文本字符串。
QPainter类的drawText()方法的基本语法
drawText(int x, int y, string text)
# x:绘制字符串的水平起始位置。
# y:绘制字符串的垂直起始位置。
# text:要绘制的字符串。
示例:绘制带噪点和干扰线的验证码
我们对验证码一定不陌生,每当用户注册或登录一个程序时大多数情况下都要求输入验证码,所有信息经过验证无误时才可以进入。
创建一个.py文件,首先定义存储数字和字母的列表,并使用随机数生成器随机产生数字或字母;然后在窗口的paintEvent()方法中创建QPainter绘图对象,使用该绘图对象的drawRect()方法绘制要显示验证码的区域,并使用drawLine()方法和drawPoint()绘制干扰线和噪点;最后设置画笔,并使用绘图对象的drawText()在指定的矩形区域绘制随机生成的验证码。
完整代码如下:
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QPainter, QFont
from PyQt5.QtCore import Qt
import random
class Demo(QWidget):
def __init__(self, parent=None):
super(Demo, self).__init__(parent)
self.resize(150, 60) # 设置窗口大小
self.setWindowTitle("绘制验证码") # 设置窗口标题
char = [] # 定义存储数字、字母的列表,用来从中生成验证码
for i in range(48, 58): # 添加0~9的数字
char.append(chr(i))
for i in range(65, 91): # 添加A~Z的大写字母
char.append(chr(i))
for i in range(97, 123): # 添加a~z的小写字母
char.append(chr(i))
# 生成随机数字或字母
def mdChar(self):
return self.char[random.randint(0, len((self.char)))]
def paintEvent(self, event):
painter = QPainter(self) # 创建绘图对象
painter.drawRect(10, 10, 100, 30)
painter.setPen(Qt.red)
# 绘制干扰线(此处设20条干扰线,可以随意设置)
for i in range(20):
painter.drawLine(
random.randint(10, 110), random.randint(10, 40),
random.randint(10, 110), random.randint(10, 40)
)
painter.setPen(Qt.green)
# 绘制噪点(此处设500个噪点,可以随意设置)
for i in range(500):
painter.drawPoint(random.randint(10, 110), random.randint(10, 40))
painter.setPen(Qt.black) # 设置画笔
font = QFont() # 创建字体对象
font.setFamily("楷体") # 设置字体
font.setPointSize(15) # 设置字体大小
font.setBold(True) # 设置粗体
font.setUnderline(True) # 设置下画线
painter.setFont(font)
for i in range(4):
painter.drawText(30 * i + 10, 30, str(self.mdChar())) # 绘制文本
if __name__ == "__main__":
import sys # 创建窗口程序
app = QApplication(sys.argv)
demo = Demo() # 创建窗口类对象
demo.show() # 显示窗口
sys.exit(app.exec_())
运行效果如下:(每一次切换窗口,验证码都会改变)
4. 绘制图像
在PyQt5窗口中绘制图像需要使用drawPixmap()方法,该方法有多种重载形式,比较常用的有如下两种:
绘制图像的drawPixmap()方法介绍
drawImage(int x, int y, QPixmap pixmap)
drawImage(int x, int y, int width, int height, QPixmap pixmap)
# 参数说明:
# x:所绘制图像的左上角的x坐标。
# y:所绘制图像的左上角的y坐标。
# width:所绘制图像的宽度。
# height:所绘制图像的高度。
# pixmap:QPixmap对象,用来指定要绘制的图像。
drawPixmap()方法中有一个参数是QPixmap对象,它表示PyQt5中的图像对象,通过使用QPixmap可以将图像显示在标签或者按钮等控件上,而且它支持的图像类型有很多,如常用的BMP、JPG、JPEG、PNG、GIF、ICO等。
QPixmap类的常用方法及说明
使用QPixmap获取图像时,可以直接在其构造函数中指定图片,用法为“QPixmap(“图片路径”)”。
示例:绘制公司Logo
创建一个.py文件,导入PyQt5相关模块,分别使用drawPixmap()的两种重载形式绘制公司的Logo。
完整代码如下:
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QPainter, QPixmap
class Demo(QWidget):
def __init__(self, parent=None):
super(Demo, self).__init__(parent)
self.setWindowTitle("使用QPainter绘制图形") # 设置窗口标题
self.resize(300, 120) # 设置窗口大小
def paintEvent(self, event):
painter = QPainter(self) # 创建绘图对象
painter.drawPixmap(10, 10, QPixmap("./image/logo.png")) # 默认大小
# painter.drawPixmap(10, 10, 290, 110, QPixmap("./image/logo.png")) # 指定大小
if __name__ == "__main__":
import sys
app = QApplication(sys.argv) # 创建窗口程序
demo = Demo() # 创建窗口类对象
demo.show() # 显示窗口
sys.exit(app.exec_())
默认原图大小的运行结果:
指定大小的运行结果: