PyQt5提供了绘制图形的API,支持绘制:

  1. 文本
  2. 各种图形(直线,点,椭圆,弧,扇形,多边形等)
  3. 图像

绘制图形需要一个类QPainter。基本的绘制过程:

# 创建QPainter对象
painter = QPainter()
​
# painter初始化
painter.begin()
​
# 绘制文本
painter.drawText(...)
​
# 结束绘制
painter.end()

还有需要注意的是,绘制的场所必须是在painterEvent方法中。而这个painterEvent事件的方法会在主窗口刚刚生成时调用(生成绘制的图形)、调整主窗口大小时调用(随着主窗口的大小比例调整绘制图像的大小比例)和关闭主窗口时调用(销毁绘制的图形)


在窗口上绘制文本

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
​
class DrawText(QWidget):def __init__(self):super(DrawText, self).__init__()self.setWindowTitle("在窗口上绘制文本")self.resize(300, 200)self.text = "Hello world"
​def paintEvent(self, event):painter = QPainter(self)painter.begin(self)# 加一个输出,观察什么情况下print("Done")# 设置画笔颜色painter.setPen(QColor(150, 43, 5))# 设置字体painter.setFont(QFont("SimSun", 25))# 指定绘图区域,对齐方式和绘制内容painter.drawText(event.rect(), Qt.AlignCenter, self.text)painter.end()
​
if __name__ == '__main__':app = QApplication(sys.argv)main = DrawText()main.show()sys.exit(app.exec_())

运行结果:

窗口刚刚弹出时,移动窗口时,放大放小窗口时,关闭窗口时。控制台上都打印了“Done”,说明在这几类情况下,主事件调用了paintEvent()方法

需要注意的是,paintEvent()是内置的事件方法,我们只是重载了,故初始化中没有调用paintEvent(),但是,实际上主循环内部自动地调用了它。所以,这个方法的名字不是我们任意起的,而是固定的(如果不是paintEvent()而是其他什么的,程序就无法正常显示绘制的内容)。

还有需要注意的是,使用painter.begin()初始化时,为了体现是固定在主窗口上创建的,必须要填入参数self

对于其中的painter.drawText()方法,需要说明其中的第一个参数:

 painter.drawText(event.rect(), Qt.AlignCenter, self.text)

第一个参数是指定的绘图区域,此处的event.rect()指的是主事件的矩形区域,也就是整个主窗口,除此之外,可以通过指定x和y来指定绘图区域,后面会讲解。


用像素点绘制正弦曲线

PyQt5中的drawPoint可以绘制一个像素点,参数是x与y。

import sys,math
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
​
class DrawPoints(QWidget):def __init__(self):super(DrawPoints, self).__init__()self.setWindowTitle("用像素点绘制正弦曲线")self.resize(300, 300)
​def paintEvent(self, event):painter = QPainter()painter.begin(self)
​painter.setPen(Qt.blue)size = self.size()
​for i in range(1000):x = 100 * (-1 + 2 * i / 1000) + size.width() / 2y = -50 * math.sin((x - size.width() / 2) * math.pi / 50) + size.height() / 2painter.drawPoint(int(x), int(y))painter.end()
​
if __name__ == '__main__':app = QApplication(sys.argv)main = DrawPoints()main.show()sys.exit(app.exec_())

运行效果:


绘制不同类型的直线

import sys,math
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
​
class DrawMultiLine(QWidget):def __init__(self):super(DrawMultiLine, self).__init__()self.setWindowTitle("绘制不同类型的直线")self.resize(300, 300)
​def paintEvent(self, event):painter = QPainter()painter.begin(self)
​# 颜色, 粗细, 线条类型(默认为Qt.SolidLine,即实线)pen = QPen(Qt.red, 3, Qt.SolidLine)painter.setPen(pen)painter.drawLine(20, 40, 250, 40)
​# 点线pen.setStyle(Qt.DashDotLine)painter.setPen(pen)painter.drawLine(20 ,80, 250, 80)
​# 点点线pen.setStyle(Qt.DashDotDotLine)painter.setPen(pen)painter.drawLine(20, 120, 250 ,120)
​# 自定义点线风格pen.setStyle(Qt.CustomDashLine)pen.setDashPattern([1, 10, 5, 8])painter.setPen(pen)painter.drawLine(20, 200, 250, 200)
​painter.end()
​
​
if __name__ == '__main__':app = QApplication(sys.argv)main = DrawMultiLine()main.show()sys.exit(app.exec_())

运行结果:

  • drawLine(a, b, c, d):从坐标为(a,b)的点绘制到(c,d)的点的线段。
  • 窗口坐标系:(a,b)代表离窗口左侧为a个像素点,离窗口最上侧为b个像素点。

绘制各种图形

绘制弧

import sys,math
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
​
class DrawAll(QWidget):def __init__(self):super(DrawAll, self).__init__()self.setWindowTitle("绘制各种图形")self.resize(300, 300)
​def paintEvent(self, event):qp = QPainter()qp.begin(self)
​qp.setPen(Qt.blue)
​# 绘制弧# 先选定绘制区域,绘制区域为矩形(QRect)# 左上角坐标为(0, 10), 长为100, 宽为100rect = QRect(0, 10, 100, 100)# 弧为圆的一部分,角度的单位是alen:1个alen等于1/16度# 下面在rect代表的区域中绘制,起始角度为0,终止角度为50度(50 * 16 alen)qp.drawArc(rect, 0, 50 * 16)
​qp.end()
​
​
if __name__ == '__main__':app = QApplication(sys.argv)main = DrawAll()main.show()sys.exit(app.exec_())

运行结果:

绘制圆:

# 通过弧绘制圆
qp.setPen(Qt.red)
qp.drawArc(120, 10, 100, 100, 0, 360 * 16)

运行结果:

可以看到,除了使用QRect对象指定绘图区域,我们还可以直接初始化QRect的四个参数直接填入drawArc函数中作为前四个参数;起始位置为0,终止为止为360度的弧就是圆。

绘制带弦的弧:

# 绘制带弦的弧
qp.drawChord(10, 120, 100, 100, 12, 130 * 16)

运行结果:

绘制扇形

# 绘制扇形
qp.drawPie(10, 240, 100, 100, 12, 130 * 16)     

运行结果:

绘制椭圆

# 绘制椭圆
qp.drawEllipse(120, 120, 150, 100)

运行结果:

绘制椭圆只需要指定绘图区域,绘制出的椭圆就是指定的矩形区域的内接椭圆。所以,我们可以通过指定正方形区域来绘制圆。

绘制5边形

 # 绘制5边形
point1 = QPoint(140, 380)
point2 = QPoint(270, 420)
point3 = QPoint(290, 512)
point4 = QPoint(290, 588)
point5 = QPoint(200, 533)
​
polygon = QPolygon([point1, point2, point3, point4, point5])
qp.drawPolygon(polygon)

运行结果:

多边形的绘制机制也蛮显然的,通过创建多个QPoint对象指定多边形的每个顶点的坐标,再用这几个代表像素点的QPoint对象去初始化一个QPolygon对象,这个QPolygon对象作为drawPolygon的参数完成绘制。

绘制图像

# 绘制图像
image = QImage("./image/pic2.png")
rect = QRect(300, 200, 300, 230)
qp.drawImage(rect, image)

运行结果:


用画刷填充图形区域

import sys,math
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
​
class FillRect(QWidget):def __init__(self):super(FillRect, self).__init__()self.setWindowTitle("用画刷填充图形区域")self.resize(360, 300)
​def paintEvent(self, event):qp = QPainter()qp.begin(self)
​# 实心画刷brush = QBrush(Qt.SolidPattern)qp.setBrush(brush)qp.drawRect(10, 15, 90, 60)
​# 点阵画刷(类型1)brush = QBrush(Qt.Dense1Pattern)qp.setBrush(brush)qp.drawRect(130, 15, 90, 60)
​# 点阵画刷(类型2)brush = QBrush(Qt.Dense2Pattern)qp.setBrush(brush)qp.drawRect(250, 15, 90, 60)
​# 点阵画刷(类型3)brush = QBrush(Qt.Dense3Pattern)qp.setBrush(brush)qp.drawRect(10, 105, 90, 60)
​# 点阵画刷(类型4)brush = QBrush(Qt.Dense4Pattern)qp.setBrush(brush)qp.drawRect(130, 105, 90, 60)
​# 点阵画刷(类型5)brush = QBrush(Qt.Dense5Pattern)qp.setBrush(brush)qp.drawRect(250, 105, 90, 60)
​# 点阵画刷(类型6)brush = QBrush(Qt.Dense6Pattern)qp.setBrush(brush)qp.drawRect(10, 195, 90, 60)
​# 点阵画刷(类型7)brush = QBrush(Qt.Dense7Pattern)qp.setBrush(brush)qp.drawRect(130, 195, 90, 60)
​# 横格画刷brush = QBrush(Qt.HorPattern)qp.setBrush(brush)qp.drawRect(250, 195, 90, 60)
​qp.end()
​
​
if __name__ == '__main__':app = QApplication(sys.argv)main = FillRect()main.show()sys.exit(app.exec_())

运行结果:

每创建一个画刷对象,都需要调用QPainter对象的setBrush()方法设置画刷。

c++ dll发消息到主窗口_PyQt5学习笔记(五)窗口图形绘制相关推荐

  1. c++ windows 点击按钮跳转另一个窗体_PyQt5学习笔记(一)窗体控制

    非本人原创,仅为笔记,与诸君共勉(`・ω・´) 课程链接: PyQt5教程,来自网易云课堂_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili​www.bilibili.com 此处为23讲之后的笔记 ...

  2. wxpython应用程序对象与顶级窗口_wxPython学习笔记(二)

    如何创建和使用一个应用程序对象? 任何wxPython应用程序都需要一个应用程序对象.这个应用程序对象必须是类wx.App或其定制的子类的一个实例.应用程序对象的主要目的是管理幕后的主事件循环. 父类 ...

  3. PowerBuilder学习笔记(窗口设计)

    一.窗口类型 1.主窗口(Main Window) 主窗口可以独立存在,不依靠其他任何窗口,在执行应用程序过程中,获得焦点时会覆盖其他窗口,当失去焦点时又会被其他窗口所覆盖. 2.子窗口(Child ...

  4. java message bus_【Microsoft Azure学习之旅】消息服务Service Bus的学习笔记及Demo示例...

    今年项目组做的是Cloud产品,有幸接触到了云计算的知识,也了解并使用了当今流行的云计算平台Amazon AWS与Microsoft Azure.我们的产品最初只部署在AWS平台上,现在产品决定同时支 ...

  5. pyqt5 自定义控件_PyQt5学习笔记(十六)Pyinstaller打包与SQLite数据库

    终于到了最后一章了QAQ,第一次写4万字以上的笔记分享,最近也在忙科创和CV的比赛,所以笔记会显得比较粗糙.其实吧分享这个笔记很大一部分是为了让自己记得更牢,网上翻阅自己的笔记也方便,如果有讲解注释不 ...

  6. 图片适应窗口_HTMLCSS学习笔记(八)-- 宽高自适应

    宽高自适应 网页布局中经常要定义元素的宽和高.但很多时候我们希望元素的大小能够根据窗口或子元素自动调整,这就是pc自适应. 自适应的优点: 元素自适应在网页布局中非常重要,它能够使网页显示更灵活,可以 ...

  7. PowerBuilder学习笔记(窗口事件和函数)

    一.窗口事件: 1.Open事件 在窗口打开后.显示前发生,系统已经构造好了窗口的所有属性和所有控件. Open(),OpenSheet()等函数会触发此事件. 2.Close事件 在窗口被关闭时发生 ...

  8. mfc e将控件置于窗口顶层_PyQt5学习笔记04 - QWidget窗口控件基类

    本来这一篇是想写一下怎么使用Qt Designer去设计一个界面的,但是我现在通常都是用代码去直接写界面很少用设计器.因为Qt Designer并不是为了python而写的,所以用起来不是很方便.很多 ...

  9. python生成一个窗口_PyQt5创建一个新窗口的实例

    更多python教程请到友情连接: 菜鸟教程www.piaodoo.com 人人影视www.sfkyty.com 飞卢小说网www.591319.com 韩剧网www.op-kg.com 兴化论坛ww ...

最新文章

  1. 【R语言学习】时间序列
  2. hdu2413 二分+二分匹配
  3. Keras中Callback函数的使用
  4. 安装Tomcat6.0
  5. BZOJ 1613: [Usaco2007 Jan]Running贝茜的晨练计划
  6. 这可能是你见过的最全的网络爬虫总结
  7. 构造函数为什么不能是虚函数
  8. 从周五开始美国服务器特别慢,美国服务器用户有同感吗?...
  9. Java TreeMap
  10. iPhone提示“软件更新失败”下载时出错怎么办?教你解决!
  11. 【信号完整性】信号反射原理
  12. element导航菜单添加搜索功能
  13. python画椭圆形_Python3 tkinter基础 Canvas create_rectangle 画虚边的矩形 create_oval 画椭圆形 圆形...
  14. ElementUI表格多选数据处理
  15. 一.对于crc校验的流程演示说明。
  16. 小陈学JS 函数练习:用户输入一个数判断是否是素数,并返弹出回值(又叫质数,只能被1和自身整数的数)
  17. 删除rbd的数据后ceph空间没有释放
  18. codesign想要访问您的钥匙串中的密钥
  19. zuk android os 流量,ZUK Z1国际版:细数Cyanogen OS的几点不同
  20. 函数传址,但无法改变xy数据问题

热门文章

  1. 前端学习(3185):ant-design的button介绍按钮属性
  2. [html] 如果一个标签元素同时出现两个class属性,两个class都会生效吗?为什么?
  3. [html] 请说说你在写布局时对于浏览器兼容性的感受或总结
  4. [html] 一般习惯把js写在</body>前,但有例外的情况吗?说说看
  5. [vue] 什么是虚拟DOM?
  6. [css] 如何使用css实现跨浏览器的最小高度?
  7. 工作289:父子组件传值控制弹窗关闭
  8. 工作80:块级元素的间隙问题
  9. 前端学习(1928)vue之电商管理系统电商系统之美化一层循环的UI结构for循环ui美化
  10. 前端学习(1313):get请求参数