pyqt支持一些简单的画图操作,比如画点或者画线等一些简单的操作。
首先是原理,就是重写paintEvent()方法实现画图(可能接触pyqt不久的话对这种实现方式感觉有点奇怪,建议先别管背后的原理,不是说就不学原理了,先会用再去关注原理,前期可以完成任务,学会原理后出现问题后,定位相关问题也比较容易)
pyqt对这种画图操作并不是提供一个直接使用的方法,而是需要重写一个方法,并且具体调用的过程也隐藏了起来,这就让新手和后面定位问题带来了些许麻烦。
以下是demo
画点
首先是需要import的
# 需要import qt相关的
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtGui import QPainter, QColor, QPen
# 需要import 其他
import sys
import random
完整demo代码
# -*- coding: utf-8 -*-
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtGui import QPainter, QColor, QPen
import sys
import random
class ExcelWindow(QWidget):
def __init__(self):
super(ExcelWindow,self).__init__()
self.init_ui()
def init_ui(self):
self.resize(200,200)
def paintEvent(self, event):
qp = QPainter()
qp.begin(self)
# 绘图的方法就写在这里就好,begin与end之间
self.drewDot(qp)
qp.end()
def drewDot(self,qp):
pen = QPen(QColor(238,0,0),3)
qp.setPen(pen) # 对画笔进行设置,QColor参数为颜色的rgb值,后面3为点的大小
print(self.size()) # 确认下能画画的画布像素范围
# 随机画几个点
for i in range(20):
# drawPoint的参数有两个,一个是点的横坐标,一个是点的纵坐标
qp.drawPoint(random.randint(0,199), random.randint(0,199))
def main():
app = QApplication(sys.argv)
gui = ExcelWindow()
gui.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
然后是运行出来的结果
画线
首先是需要import的
# 需要import qt相关的
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtGui import QPainter, QColor, QPen
# 需要import 其他
import sys
import random
完整demo代码
# -*- coding: utf-8 -*-
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtGui import QPainter, QColor, QPen
from PyQt5.QtCore import Qt
import sys
import random
'''
天依蓝 #66ccff 102,204,255
初音绿 #66ffcc 102,255,204
言和绿 #99ffff 153,255,255
阿绫红 #ee0000 238,0,0
双子黄 #ffff00 255,255,0
'''
class ExcelWindow(QWidget):
def __init__(self):
super(ExcelWindow,self).__init__()
self.init_ui()
def init_ui(self):
self.resize(200,200)
def paintEvent(self, event):
qp = QPainter()
qp.begin(self)
# 绘图的方法就写在这里就好,begin与end之间
self.drewLines(qp)
qp.end()
def drewLines(self,qp):
pen = QPen(QColor(238,0,0), 2, Qt.SolidLine)
qp.setPen(pen) # 对画笔进行设置,QColor参数为颜色的rgb值,后面2为线的宽,Qt.SolidLine是线的种类
print(self.size()) # 确认下能画画的画布像素范围
# 随机画几个线段
for i in range(5):
# 四个参数分别是横坐标的起始位置,纵坐标的起始位置,横坐标的最终位置,纵坐标的最终位置
qp.drawLine(random.randint(0,199), random.randint(0,199), random.randint(0,199), random.randint(0,199))
def main():
app = QApplication(sys.argv)
gui = ExcelWindow()
gui.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
画文字
写到这这个编辑器卡bug了,辣鸡。。。。。算逑,不写画文字的代码了,跟上面差不多。
顺手贴下v家的色值吧
'''
天依蓝 #66ccff 102,204,255
初音绿 #66ffcc 102,255,204
言和绿 #99ffff 153,255,255
阿绫红 #ee0000 238,0,0
双子黄 #ffff00 255,255,0
'''
然后是这个setPen的参数(设置用于绘制的笔的颜色、大小和样式)
颜色可以用QColor,参数可以写rgb三个值也可以直接写qt内置的颜色
QColor(238,0,0)
QColor(Qt.green)
样式如下表格
参数 | 描述 |
---|---|
Qt.NoPen | 没有线 |
Qt.SolidLine | 一条简单的线 |
Qt.DashLine | 由一些像素分隔的短线 |
Qt.DotLine | 由一些像素分隔得点 |
Qt.DashDotLine | 轮流交替的点和短线 |
Qt.DashDotDotLine | 一条短线、两个点 |
Qt.MPenStyle | 画笔风格的掩码 |
还有这个的基本原理,新手的话看类和方法里面都没有直接调用这个paintEvent,它怎么就能画出来了?
一个基本的理解啊,就是这个paintEvent已经涉及到pyqt的窗口内部机制了,建议别太重度使用,它的使用机制和刷新机制都不是很容易理解的,也就是一个方法的调用和刷新很可能都不在你的控制下,当然如果理解了机制之后再使用就比较容易控制了。
首先是使用,这个paintEvent不能直接调用,而是需要重写好相关内部的操作后等待窗口的绘制事件。
绘制的自动触发机制如下:
- 窗口第一次显示时,
- 窗口大小调整时,
- 窗口切换或遮挡,
以上操作系统会自动产生一个绘图事件,强制这个paintEvent的运行;
绘制的”手动“触发机制:
这里的手动不是手动操作正在运行的窗口程序,而是在程序中使用update或者repaint进行重绘
- repaint()函数会强制产生一个即时的重绘事件;
- update()函数只是在Qt下一次处理事件时才调用一次绘制事件
多次调用update(),Qt会把连续多次的绘制事件压缩成一个单一的绘制事件,这样可避免闪烁现象。
所以建议在需要重绘的时候尽量使用update,在必须实时显示绘制的时候使用repaint
self.update()