首页 > 其他分享 >31. 绘图技术

31. 绘图技术

时间:2025-01-19 17:31:42浏览次数:1  
标签:__ None Qt int 31 float 技术 Union 绘图

一、QPainter绘图

  绘图是指在绘图设备(窗口、控件、图像、打印机等)上将用户构思出的图形绘制出来,图形包括点、线、矩形、多边形、椭圆、文字及保存到磁盘上的图像等。可以对绘制的图形进行处理,如给封闭的图形填充颜色。

  绘图设备是从 QPaintDevice 继承的类,包括继承自 QWidget 的窗口、各种控件、QPixmap 和 QImage。如果绘图设备是窗口或控件,则 QPainter 绘图一般放到 paintEvent() 事件或者被 paintEvent() 事件调用的函数中。

  我们可以在终端中使用 pip 安装 pyside6 模块。

pip install pyside6

  用 QPainter 类创建绘图实例的方法如下:

QPainter()
QPainter(device=QPaintDevice)

  其中 QPaintDevice 是指继承自 QPaintDevice 的绘图设备。如果使用不带设备的 QPainter() 方法创建实例对象,,则在开始绘图前需要用 painter.begin(QPaintDevice) 方法指定绘图设备,此时 painter.isActive() 的返回值是 True,绘图完成后,需要用 painter.end() 方法声明完成绘图,之后可以用 begin() 方法重新指定绘图设备。begin()end() 方法都返回 bool 值。

  QPainter 类常用对状态进行设置的方法如下:

setBackground(bg:Union[QBursh, Qt.BrushStyle, Qt.GlobalColor, QColor, QGradient, QImage, QPixmap]) -> None  # 设置背景色,背景色只对不透明的文字、虚线或位图起作用
setBackgroundMode(mode:Qt.BGMode) -> None                                                                   # 设置透明或不透明背景模式

setFont(f:Union[QFont, str, Sequence[str]]) -> None                                                         # 设置字体
setLayoutDirection(direction:Qt.LayoutDirection) -> None                                                    # 设置布局方向
setOpacity(opacity:float) -> None                                                                           # 设置不透明度

setBrush(brush:Union[QBrush, Qt.BrushStyle,n Qt.GlobalColor, QColor, QGradient, QImage, QPixmap]) -> None   # 设置画刷
setBrush(style:Qt.BrushStyle) -> None                                                                       # 设置画刷
setBrushOrigin(arg__1:Union[QPointF, QPoint, QPainterPath.Element]) -> None                                 # 设置画刷的起点
setBrushOrigin(x:int, y:int) -> None                                                                        # 设置画刷的起点

setPen(pen:Union[QPen, Qt.PenStyle, QColor]) -> None                                                        # 设置钢笔
setPen(color:Union[QColor, Qt.GlobalColor, str]) -> None                                                    # 设置钢笔

setClipPath(path:QPainterPath, op:Qt.ClipOperation=Qt.ReplaceClip) -> None                                  # 设置剪切路径
setClipRect(rect:QRect, op:Qt.ClipOperation=Qt.ReplaceClip) -> None                                         # 设置剪切矩形区域
setClipRect(arg_1:Union[QRectF, QRect], op:Qt.ClipOperation=Qt.ReplaceClip) -> None                         # 设置剪切矩形区域
setClipRect(x:int, y:int, w:int, h:int, op:Qt.ClipOperation=Qt.ReplaceClip) -> None                         # 设置剪切矩形区域
setClipRegion(arg__1:Union[QRegion, QBitmap, QPolygon, QRect], op=Qt.ReplaceClip) -> None                   # 设置剪切区域
setClipping(enable:bool) -> None                                                                            # 设置是否启动剪切

setCompositionMode(mode:QPainter.CompositionMode) -> None                                                   # 设置图形的合成模式

setRenderHint(hint:QPainter.RenderHint, on:bool=true) -> None                                               # 设置渲染模式
setRenderHints(hints:QPainter.RenderHints, on:bool=true) -> None                                            # 设置多个渲染模式

setTransform(transform:QTransform, combine:bool=false) -> None                                              # 设置全局变化矩阵
setWorldTransform(matrix:QTransform, combine:bool=false) -> None                                            # 设置全局变化矩阵
setViewTransformEnabled(enable:bool) -> None                                                                # 设置是否启动视图变换
setViewport(viewport:QRect) -> None                                                                         # 设置视口
setViewport(x:int, y:int, w:int, h:int) -> None                                                             # 设置视口
setWindow(window:QRect) -> None                                                                             # 设置逻辑窗口
setWindow(x:int, y:int, w:int, h:int) -> None                                                               # 设置逻辑窗口
setWorldMatrixEnabled(enabled:bool) -> None                                                                 # 设置是否启动全局矩阵变换

save() -> None                                                                                              # 保存状态到堆栈中
restore() -> None                                                                                           # 从堆栈中恢复状态

二、设置钢笔

  钢笔 QPen 用于绘制线条,线条有样式(实线、虚线、点虚线)、颜色、宽度等属性,用 QPainter 的 setPen(QPen) 方法为 QPainter 设置钢笔。

  用 QPen 创建钢笔的方法如下:

QPen()
QPen(s:Qt.PenStyle)
QPen(brush:Union[QBrush, Qt.BrushStyle, Qt.GlobalColor, QColor, QGradient, QImage, QPixmap], width:float, s:Qt.PenStyle=Qt.SolidLine, c:Qt.PenCapstyle=Qt.SquareCap, j:Qt.PenJoinstyle=Qt.BevelJoin)
QPen(color:Union[QColor, Qt.GlobalColor, str, int])
QPen(pen:Union[QPen, Qt.PenStyle, QColor])

  其中 s 是 Qt.PenStyle 的枚举值,用于设置钢笔的样式;画刷 brush 可以用 QBrush、QColor、Qt.GlobalColor 和 QGradient 来设置;c 是 Qt.PenCapStyle 的枚举值,用于设置线条端点样式;j 是 Qt.PenJoinStyle 的枚举值,用于设置线条连接点处的样式。钢笔默认的颜色是黑色,宽度是 1 像素,样式是实线,端点样式是 Qt.SquareCap,连接处是 Qt.BevelJoin。

  QPen 类的常用方法如下:

setStyle(arg__1:Qt.PenStyle) -> None                                                                        # 设置线条样式
style() - Qt.PenStyle                                                                                       # 获取线条样式
setWidth(width:int) -> None                                                                                 # 设置线条宽度
setWidth(width:float) -> None                                                                               # 设置线条宽度
isSolid() -> bool                                                                                           # 获取线条样式是否是实现填充
setBrush(brush:Union[QBrush, Qt.BrushStyle, QColor, Qt.GlobalColor, QGradient, QImage, QPixmap]) -> None    # 设置画刷
brush() -> QBrush                                                                                           # 获取画刷
setCapStyle(pcs:Qt.PenCapStyle) -> None                                                                     # 设置线端部的样式
capStyle() -> Qt.PenCapStyle                                                                                # 获取线端部的样式
setColor(color:Union[QColor, Qt.GlobalColor, str, int]) -> None                                             # 设置颜色
color() -> QColor                                                                                           # 获取颜色
setCosmetic(cosmetic:bool) -> None                                                                          # 设置是否进行装饰
isCosmetic() -> bool                                                                                        # 获取是否进行装饰
setDashOffset(doffset:float) -> None                                                                        # 设置虚线开始绘制的点与线起始点的距离
setDashPattern(pattern:Sequence[float]) -> None                                                             # 设置用户自定义虚线样式
setJoinStyle(pcs:Qt.PenJoinStyle) -> None                                                                   # 设置两相交线连接点出的样式
setMiterLimit(limit:float) -> None                                                                          # 设置斜接延长线的长度

  线条的宽度用 setWidth(int)setWidthF(float) 方法设置,如果宽度始终为 0,表示是装饰线条;装饰线条也可用 setCosmetic(bool) 方法设置。装饰线条是指具有恒定宽度的边,可确保线条在不同缩放比例下具有相同的宽度。

  线条的样式用 setStyle(Qt.PenStyle) 方法设置,参数 Qt.PenStyle 可取的值如下所示。

Qt.PenStyle.NoPen               # 不绘制线条
Qt.PenStyle.SolidLine           # 实线
Qt.PenStyle.DashLine            # 虚线
Qt.PenStyle.DotLine             # 点线
Qt.PenStyle.DashDotLine         # 点画线
Qt.PenStyle.DashDotDotLine      # 双点划线
Qt.PenStyle.CustomDashLine      # 自定义线

钢笔的样式

  钢笔的端点样式用 setCapStyle(Qt.PenCapStyle) 方法设置,其中参数 Qt.PenCapStyle 可取值如下:

Qt.PenCapStyle.FlatCap          # 不包含端点
Qt.PenCapStyle.SquareCap        # 包含端点
Qt.PenCapStyle.RoundCap         # 包含端点,并延长半个宽度

钢笔的端点

  两个线条连接点处的样式用 setJoinStyle(Qt.PenJoinStyle) 方法设置,其中参数 Qt.PenJoinStyle 可取值如下:

Qt.PenJoinStyle.MiterJoin
Qt.PenJoinStyle.BevelJoin
Qt.PenJoinStyle.RoundJoin
Qt.PenJoinStyle.SvgMiterJoin

线条连接样式

  线条连接样式是 Qt.MiterJoin 时,用 setMiterLimit(float) 方法设置延长线的长度,其中参数 float 是线条宽度的倍数,默认是2.0,其延长线的含义如下所示。

延长线

  用 setDashPattern(Sequence[float]) 方法可以自定义虚线样式,其中参数的奇数项表示实线的长度,偶数项表示空白处的长度,长度以线宽为单位,表示为线宽的倍数。

  用 setDashOffset(float) 方法可以设置虚线开始绘制的点与线起始点之间的距离,如果这个距离是动态的,则会形成动画效果。

import sys

from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtGui import QPainter, QPen
from PySide6.QtCore import Qt, QPointF

class MyWidget(QWidget):
    def __init__(self):
        # 1、调用父类的__init__()方法
        super().__init__()
        # 2、设置窗口对象大小
        self.resize(700, 500)

    def paintEvent(self, event):

        # 1、创建绘图对象
        painter = QPainter(self)
        # 2、创建画笔对象
        pen = QPen()

        # 3、设置线条颜色
        pen.setColor(Qt.GlobalColor.blue)
        # 4、设置线条的宽度
        pen.setWidth(10)
        # 5、设置线条样式
        pen.setStyle(Qt.PenStyle.DashDotDotLine)
        # 6、设置线条的端点样式
        pen.setCapStyle(Qt.PenCapStyle.RoundCap)
        # 7、设置两个线条连接点处的样式
        pen.setJoinStyle(Qt.PenJoinStyle.RoundJoin)

        # 8、设置画笔
        painter.setPen(pen)

        # 0、绘制一条折线
        p1 = QPointF(50, 50)
        p2 = QPointF(self.width() - 50, 50)
        p3 = QPointF(50, self.height() - 50)
        p4 = QPointF(self.width() - 50, self.height() - 50)
        painter.drawPolyline([p1, p2, p3, p4])

if __name__ == "__main__":
    # 1、创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2、创建一个窗口
    window = MyWidget()
    # 3、展示窗口
    window.show()
    # 4、进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

三、设置画刷

  对于封闭的图形,如矩形、圆等,用画刷 QBrush 可以在其内部填充颜色、样式、渐变、纹理或图案。

  用 QBrush 类创建画刷的方法如下所示。

QBrush()
QBrush(brush:Union[QBrush, Qt.BrushStyle, Qt.GlobalColor, QColor, QGradient, QImage, QPixmap])
QBrush(bs:Qt.BrushStyle)
QBrush(color:Qt.GlobalColor, bs:Qt.BrushStyle=Qt.SolidPattern)
QBrush(color:Qt.GlobalColor, pixmap:Union[QPixmap, QImage, str])
QBrush(color:Union[QColor, Qt.GlobalColor, str], bs:Qt.BrushStyle=Qt.SolidPattern)
QBrush(color:Union[QColor, Qt.GlobalColor, str], pixmap:Union[QPixmap, QImage, str])
QBrush(gradient:Union[QGradient, QGradient.Preset])
QBrush(image:Union[QImage, str])
QBrush(pixmap:Union[QPixmap, QImage, str])

  QBrush 类的常用方法如下:

setStyle(arg__1:Qt.BrushStyle) -> None                      # 设置风格
style() -> Qt.BrushStyle                                    # 获取风格
setTexture(pixmap:QPixmap) -> None                          # 设置纹理图片
texture() -> QPixmap                                        # 获取纹理图片
setTextureImage(image:QImage) -> None                       # 设置纹理图片
textureImage() -> QImage                                    # 获取纹理图片
setColor(color:Union[QColor, Qt.GlobalColor, str]) -> None  # 设置颜色
color() -> QColor                                           # 获取颜色
gradient() -> QGradient                                     # 获取渐变色
setTransform(arg__1:QTransform) -> None                     # 设置变换矩阵
transform() -> QTransform                                   # 获取变换矩阵
isOpaque() -> bool                                          # 设置是否不透明

  画刷的风格用 setStyle(Qt.BrushStyle) 方法设置,其中参数 Qt.BrushStyle 的取值如下所示:

Qt.BrushStyle.SolidPattern
Qt.BrushStyle.Dense1Pattern
Qt.BrushStyle.Dense2Pattern
Qt.BrushStyle.Dense3Pattern
Qt.BrushStyle.Dense4Pattern
Qt.BrushStyle.Dense5Pattern
Qt.BrushStyle.Dense6Pattern
Qt.BrushStyle.Dense7Pattern
Qt.BrushStyle.HorPattern
Qt.BrushStyle.VerPattern
Qt.BrushStyle.CrossPattern
Qt.BrushStyle.BDiagPattern
Qt.BrushStyle.FDiagPattern
Qt.BrushStyle.DiagCrossPattern
Qt.BrushStyle.TexturePattern
Qt.BrushStyle.NoBrush

画刷的样式

  画刷的纹理可以用 setTexture(QPixmap)setTextureImage(QImage) 方法来设置,这时样式被设置成 Qt.TexturePattern。

import sys

from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtGui import QPainter, QBrush
from PySide6.QtCore import Qt, QPointF, QRectF

class MyWidget(QWidget):
    def __init__(self):
        # 1、调用父类的__init__()方法
        super().__init__()
        # 2、设置窗口对象大小
        self.resize(700, 500)

    def paintEvent(self, event):
        # 1、创建绘图对象
        painter = QPainter(self)
        # 2、创建画刷对象
        brush = QBrush()

        # 3、设置画刷颜色
        brush.setColor(Qt.GlobalColor.blue)
        # 4、设置画刷样式
        brush.setStyle(Qt.BrushStyle.CrossPattern)

        # 5、设置画刷
        painter.setBrush(brush)

        # 6、绘制一个矩形
        p1 = QPointF(self.width() / 4, self.height() / 4)
        p2 = QPointF(3 * self.width() / 4, 3 * self.height() / 4)
        painter.drawRect(QRectF(p1, p2))

if __name__ == "__main__":
    # 1、创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2、创建一个窗口
    window = MyWidget()
    # 3、展示窗口
    window.show()
    # 4、进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

四、渐变色

  在用画刷进行填充时,可以设置填充颜色为渐变色。所谓渐变色是指在两个不重合的点处分别设置不同的颜色,这两个点一个是起点,另一个是终点,这两个点之间的颜色从起点的颜色逐渐过渡到终点的颜色。

  定义渐变色的类是 QGradient,渐变样式分为 3 种类型,分别为 线性渐变 QLinearGradient、径向渐变 QRadialGradient 和 圆锥渐变 QConicalGradient,它们都继承自 QGradient 类,也会继承 QGradient 类的属性和方法。

渐变样式

  用 QLinearGradient 类创建线性渐变色的方法如下所示。线性渐变需要一个线性渐变矩形区域(起始和终止位置),参数用于确定这个矩形区域。

QLinearGradient()
QLinearGradient(start:Union[QPointF, QPoint, QPainterPath.Element], finalStop:Union[QPointF, QPainterPath.Element])
QLinearGradient(xStart:float, yStart:float, xFinalStop:float, yFinalStop:float)

  用 QRadialGradient 类创建径向渐变色的方法如下。径向渐变需要的几何参数下所示,需要确定圆心位置、半径、焦点位置和焦点半径。径向渐变的构造函数中,第 1 个参数是圆心位置,可以用点或坐标定义;第 2 个参数是半径;第 3 个参数是焦点位置,可以用点或坐标定义;第 4 个参数是焦点半径。如果焦点设置到圆的外面,则取圆上的点作为焦点。

QRadialGradient()
QRadialGradient(center:Union[QPointF, QPoint, QPainterPath.Element], centerRadius:float, focalPoint:Union[QPointF, QPoint, QPainterPath.Element], focalRadius:float)
QRadialGradient(center:Union[QPointF, QPoint, QPainterPath.Element], radius:float)
QRadialGradient(center:Union[QPointF, QPoint, QPainterPath.Element], radius:float, focalPoint:Union[QPointF, QPoint, QPainterPath.Element])
QRadialGradient(cx:float, cy:float, centerRadius:float, fx:float, fy:float, focalRadius:float)
QRadialGradient(cx:float, cy:float, radius:float)
QRadialGradient(cx:float, cy:float, radius:float, fx:float, fy:float)

  用 QConicalGradient 创建圆锥渐变色的方法如下所示。圆锥渐变需要的几何参数为圆心位置和起始角度 a,角度必须在 0°~360° 之间,圆心位置可以用点或坐标来定义。

QConicalGradient()
QConicalGradient(center:Union[QPointF, QPoint, QPainterPath.Element], startAngle:float)
QConicalGradient(cx:float, cy:float, startAngle:float)

径向渐变和圆锥渐变的几何参数

  QLinearGradient、QRadialGradient 和 QConicalGradient 继承自 QGradient,因此也会继承 QGradient 的方法。QGradient 类的常用方法如下:

setCoordinateMode(mode:QGradient.CoordinateMode) -> None                    # 设置坐标模式
setColorAt(pos:float, color:Union[QColor, Qt.GlobalColor, str]) -> None     # 设置颜色
setStops(stops:Sequence[Tuple[float, QColor]]) -> None                      # 设置颜色
setInterpolationMode(mode:QGradient.InterpolationMode) -> None              # 设置插值模式
setSpread(spread:QGradient.Spread) -> None                                  # 设置扩展模式
type() -> QGradient.Type                                                    # 获取类型

  在渐变区域内,可以在多个点设置颜色值,这些点之间的颜色值根据两侧的颜色来确定。在定义内部点的颜色值时,通常通过逻辑坐标来定义,渐变区域内的起始点的逻辑值是 0,终止点的逻辑值是 1。如果要在中间位置定义颜色,可以用 setColorAt() 方法来定义。我们也可以用 setStops() 方法一次定义多个颜色值。

  用 setCoordinateMode(QGradient.CoordinateMode) 方法可以设置坐标的模式,参数 QGradient.CoordinateMode 的取值如下所示。

QGradient.CoordinateMode.LogicalMode            # 逻辑方式,起始点为0,终止点为1,这是默认值
QGradient.CoordinateMode.ObjectMode             # 相对于绘图区域矩形边界的逻辑坐标,左上角的坐标是(0, 0),右下角的坐标是(1, 1)
QGradient.CoordinateMode.StretchToDeviceMode    # 相对于绘图设备矩形边界的逻辑坐标,左上角的坐标是(0, 0),右下角的坐标是(1, 1)
QGradient.CoordinateMode.ObjectBoundingMode     # 与ObjectMode基本相同,除了QBrush.transform()应用与逻辑空间而不是物理空间

  当设置的渐变区域小于填充区域时,渐变颜色可以扩展到渐变区域以外的空间。扩展模式用 setSpread(QGradient.Spread) 方法定义,参数 QGradient.Spread 的取值如下所示。扩展模式不适合圆锥渐变,圆锥渐变没有固定的边界。

QGradient.Spread.PadSpread          # 用最近的颜色扩展
QGradient.Spread.RepeatSpread       # 重复渐变
QGradient.Spread.ReflectSpread      # 对称渐变

  用 setInterpolationMode(mode:QGradient.InterpolationMode) 方法设置渐变色内部的插值模式,参数可取值如下:

QGradient.InterpolationMode.ColorInterpolation
QGradient.InterpolationMode.ComponentInterpolation

  用 type() 方法可以获取渐变类型,返回值可能如下:

QGradient.Type.LinearGradient
QGradient.Type.RadialGradient
QGradient.Type.ConicalGradient
QGradient.Type.NoGradient        # 无渐变色

  QLinearGradient 类的常用方法:

setStart(start:Union[QPontF, QPoint, QPainterPath.Element]) -> None     # 设置起始点
setStart(x:float, y:float) -> None                                      # 设置起始点
start() -> QPointF                                                      # 获取起始点
setFinalStop(stop:Union[QPontF, QPoint, QPainterPath.Element]) -> None  # 设置终止点
setFinalStop(x:float, y:float) -> None                                  # 设置终止点
finalStop() -> QPointF                                                  # 获取终止点

  QRadialGradient 类的常用方法:

setCenter(center:Union[QPointF, QPoint]) -> None                                # 设置圆心
setCenter(x:float, y:float) -> None                                             # 设置圆心
setRadius(radius:float) -> None                                                 # 设置半径
setCenterRadius(radius:float) -> None                                           # 设置半径
setFocalPoint(focalPoint:Union[QPointF, QPoint, QPainterPath.Element]) -> None  # 设置焦点位置
setFocalPoint(x:float, y:float) -> None                                         # 设置焦点位置
setFocalRadius(radius:float) -> None                                            # 设置焦点半径

  QConicalGradient 类的常用方法:

setCenter(center:Union[QPointF, QPoint]) -> None            # 设置圆心
setCenter(x:float, y:float) -> None                         # 设置圆心
setAngle(angle:float) -> None                               # 设置起始角度
import sys

from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtGui import QPainter, QPen, QBrush
from PySide6.QtGui import QLinearGradient, QRadialGradient, QConicalGradient
from PySide6.QtCore import Qt, QPointF, QRectF

class MyWidget(QWidget):
    def __init__(self):
        # 1、调用父类的__init__()方法
        super().__init__()
        # 2、设置窗口对象大小
        self.resize(700, 500)

    def paintEvent(self, event):
        w = self.width()
        h = self.height()

        # 1、创建绘图对象
        painter = QPainter(self)

        # 2.1、创建钢笔对象,绘制边框
        pen = QPen()
        # 2.2、设置边框宽度
        pen.setWidth(5)
        # 2.3、设置边框颜色
        pen.setColor(Qt.GlobalColor.darkBlue)
        # 2.4、设置边框样式
        pen.setStyle(Qt.PenStyle.DashLine)
        # 2.5、设置钢笔
        painter.setPen(pen)

        # 3.1、线性渐变
        linear = QLinearGradient(QPointF(0, 0), QPointF(w / 8, 0))
        # 3.2、设置颜色
        linear.setStops([(0, Qt.GlobalColor.red), (0.3, Qt.GlobalColor.yellow), (0.6, Qt.GlobalColor.green), (1, Qt.GlobalColor.blue)])
        # 3.3、设置扩展模式
        linear.setSpread(QLinearGradient.Spread.ReflectSpread)
        # 3.4、用线性渐变定义画刷
        brush = QBrush(linear)
        # 3,5、设置画刷
        painter.setBrush(brush)
        # 3.6、绘制矩形
        painter.drawRect(QRectF(0, 0, w / 2, h / 2))

        # 4.1、镜像渐变
        radial = QRadialGradient(QPointF(w / 4 * 3, h / 4), w / 8, QPointF(w / 4 * 3, h / 4), w / 15)
        # 4.2、设置颜色
        radial.setColorAt(0, Qt.GlobalColor.red)
        radial.setColorAt(0.5, Qt.GlobalColor.yellow)
        radial.setColorAt(1, Qt.GlobalColor.blue)
        # 4.3、设置扩展模式
        radial.setSpread(QRadialGradient.Spread.RepeatSpread)
        # 4.4、用镜像渐变创建画刷
        brush = QBrush(radial)
        # 4.5、设置画刷
        painter.setBrush(brush)
        # 4.6、绘制矩形
        painter.drawRect(QRectF(w / 2, 0, w / 2, h / 2))

        # 5.1、圆锥渐变
        conical = QConicalGradient(QPointF(w / 4, h / 4 * 3), h / 6)
        # 5.2、设置开始角度
        conical.setAngle(60)
        # 5.3、设置颜色
        conical.setColorAt(0, Qt.GlobalColor.red)
        conical.setColorAt(1, Qt.GlobalColor.yellow)
        # 5.4、以圆锥渐变创建画刷
        brush = QBrush(conical)
        # 5.5、设置画刷
        painter.setBrush(brush)
        # 5.6、绘制矩形
        painter.drawRect(QRectF(0, h / 2, w / 2, h / 2))

        # 6.1、镜像渐变
        radial = QRadialGradient(QPointF(w / 4 * 3, h / 4 * 3), w / 6, QPointF(w / 5 * 4, h / 5 * 4), w / 10)
        # 6.2、设置颜色
        radial.setColorAt(0, Qt.GlobalColor.red)
        radial.setColorAt(0.5, Qt.GlobalColor.yellow)
        radial.setColorAt(1, Qt.GlobalColor.blue)
        # 6.3、设置扩展模式
        radial.setSpread(QRadialGradient.Spread.ReflectSpread)
        # 6.4、用镜像渐变创建画刷
        brush = QBrush(radial)
        # 6.5、设置画刷
        painter.setBrush(brush)
        # 6.6、绘制矩形
        painter.drawRect(QRectF(w / 2, h / 2, w / 2, h / 2))

if __name__ == "__main__":
    # 1、创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2、创建一个窗口
    window = MyWidget()
    # 3、展示窗口
    window.show()
    # 4、进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

五、绘制几何图形

  QPainter 可以在绘图设备上绘制点、直线、折线、矩形、椭圆、弧、弦、文本和图像等。

5.1、绘制点

  QPainter 可以一次绘制一个点,也可以一次绘制多个点,其中 QPolygon 和 QPolygonF 是用于存储多个 QPoint 和 QPointF 的类。

# 绘制单点
drawPoint(x:int, y:int) -> None
drawPoint(p:QPoint) -> None
drawPoint(pt:Union[QPointF, QPoint]) -> None
drawPoint(pt:QPainterPath.Element) -> None

# 绘制多点
drawPoints(arg__1:Sequence[QPointF]) -> None
drawPoints(arg__1:Sequence[QPoint]) -> None
drawPoints(points:Union[QPolygon, Sequence[QPoint], QRect])
drawPoints(points:Union[QPolygon, Sequence[QPoint], QPolygon, QRectF])

  创建 QPolygon 实例的方法如下:

QPolygon()
QPolygon(arg_1:Sequence[QPoint])

  创建 QPolygonF 实例的方法如下:

QPolygonF()
QPolygonF(arg_1:Sequence[Union[QPointF,QPoint]])

  用 QPolygon 的 append(QPoint) 方法可以添加点,用 insert(int,QPoint) 方法可以插入点,用 setPoint(int,QPoint) 方法可以更改点;用 QPolygonF 的 append(Union[QPointF,QPoint]) 方法可以添加点,用 insert(int,Union[QPointF,QPoint]) 方法可以插入点。

import sys

from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtGui import QPainter, QPen, QBrush
from PySide6.QtCore import QPoint

class MyWidget(QWidget):
    def __init__(self):
        # 1、调用父类的__init__()方法
        super().__init__()
        # 2、设置窗口对象大小
        self.resize(700, 500)

    def paintEvent(self, event):
        # 1、创建绘图对象
        painter = QPainter(self)

        # 2.1、创建钢笔对象
        pen = QPen()
        # 2.2、设置钢笔的颜色
        pen.setColor("red")
        # 2.3、设置钢笔的宽度
        pen.setWidth(10)
        # 2.4、使用钢笔对象
        painter.setPen(pen)

        # 3、绘制点
        painter.drawPoint(QPoint(self.width() // 2, self.height() // 2))

if __name__ == "__main__":
    # 1、创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2、创建一个窗口
    window = MyWidget()
    # 3、展示窗口
    window.show()
    # 4、进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

5.2、绘制直线

  绘制直线需要用两个点。可以一次绘制一条直线,也可一次绘制多条直线,其中 QLine 或 QLineF 是 2D 直线类。

# 绘制单条直线
drawLine(line:QLine) -> None
drawLine(line:Union[QLineF, QLine]) -> None
drawLine(p1:QPoint, p2:QPoint) -> None
drawLine(p1:Union[QPointF, QPoint], p2:Union[QPointF, QPoint]) -> None
drawLine(x1:int, y1:int, x2:int, y2:int) -> None

# 绘制多条直线
drawLines(lines:Sequence[QLine]) -> None
drawLines(lines:Sequence[QLineF]) -> None
drawLines(pointPairs:Sequence[QPoint]) -> None
drawLines(pointPairs:Sequence[QPointF]) -> None

  用 QLine 类定义直线实例的方法如下:

QLine()
QLine(p1:QPoint, p2:QPoint)
QLine(x1:int, y1:int, x2:int, y2:int)

  用 QLineF 类定义直线实例的方法如下:

QLineF()
QLineF(line:QLine)
QLineF(p1:Union[QPointF,QPoint], p2:Union[QPointF,QPoint])
QLineF(x1:float, y1:float, x2:float, y2:float)

  用 QLine 的 setLine(x1:int,y1:int,x2:int,y2:int) 方法、setP1(QPoint) 方法、setP2(QPoint)setPoints(QPoint,QPoint) 方法可以设置线两端的点。QLineF 也有同样的方法,只需把参数 int 改成 float,或 QPoint 改成 QPointF。

  在绘制几何图像和文字时,如果线条是斜线,对线条进行放大后会发现它呈现锯齿状。为防止出现锯齿状,需要对线条边缘进行模糊化处理。用 QPainter 的 setRenderHint(hint:QPainter.RenderHint,on:bool=True)setRenderHints(hints:QPainter.RenderHints,on:bool=True) 方法可以设置是否进行抗锯齿处理,用 testRenderHint(hint:QPainter.RenderHint) 方法可以获取是否设置了抗锯齿算法,其中枚举参数 QPainter.RenderHint 可以取值如下:

QPainter.RenderHint.Antialiasing               # 启用抗锯齿
QPainter.RenderHint.TextAntialiasing           # 对文本进行抗锯齿
QPainter.RenderHint.SmoothPixmapTransform      # 使用平滑的像素图像算法
QPainter.RenderHint.LosslessImageRendering     # 用于PDF文档
import sys

from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtGui import QPainter
from PySide6.QtCore import QPoint

class MyWidget(QWidget):
    def __init__(self):
        # 1、调用父类的__init__()方法
        super().__init__()
        # 2、设置窗口对象大小
        self.resize(700, 500)

    def paintEvent(self, event):
        # 1、创建绘图对象
        painter = QPainter(self)
        # 2、绘制直线
        painter.drawLine(QPoint(0, 0), QPoint(self.width(), self.height()))
        # 3.抗锯齿
        painter.setRenderHint(QPainter.RenderHint.Antialiasing, True)

if __name__ == "__main__":
    # 1、创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2、创建一个窗口
    window = MyWidget()
    # 3、展示窗口
    window.show()
    # 4、进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

5.3、绘制折线

  绘制折线必须用两个点,即使两条折线的终点和起始点相同,每条折线也必须用两个点来定义。折线由多个折线段构成,绘制折线需要给出多个点,上个折线段的终点是下个折线段的起始点。

drawPolyline(arg__1:Sequence[QPoint]) -> None
drawPolyline(arg__1:Sequence[QPointF]) -> None
drawPolyline(polygon:Union[QPolygon, Sequence[QPoint], QRect]) -> None
drawPolyline(polygon:Union[QPolygonF, Sequence[QPointF], QRectF]) -> None
import sys

from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtGui import QPainter
from PySide6.QtCore import QPoint

class MyWidget(QWidget):
    def __init__(self):
        # 1、调用父类的__init__()方法
        super().__init__()
        # 2、设置窗口对象大小
        self.resize(700, 500)

    def paintEvent(self, event):
        # 1、创建绘图对象
        painter = QPainter(self)

        p1 = QPoint(10, 10)
        p2 = QPoint(self.width() - 10, 10)
        p3 = QPoint(10, self.height() - 10)
        p4 = QPoint(self.width() - 10, self.height() - 10)

        # 2、绘制折线
        painter.drawPolyline([p1, p2, p3, p4])

if __name__ == "__main__":
    # 1、创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2、创建一个窗口
    window = MyWidget()
    # 3、展示窗口
    window.show()
    # 4、进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

5.4、绘制矩形

  QPainter 可以一次绘制一个矩形,也可以一次绘制多个矩形。

# 绘制单个矩形
drawRect(rect:QRect) -> None
drawRect(rect:Union[QRect, QRectF]) -> None
drawRect(x1:int, y1:int, w:int, h:int) -> None

# 绘制多个矩形
drawRects(rectangles:Sequence[QRect]) -> None
drawRects(rectangles:Sequencep[QRectF]) -> None

  其中 drawRect(x1:int,y1:int,w:int,h:int) 方法中 x1 和 y1 参数确定左上角的位置,w 和 h 参数确定宽度和高度。

  圆角矩形是在矩形的基础上对 4 个角分别用一个椭圆进行倒圆角。要绘制圆角矩形,除了需要设置绘制矩形的参数外,还需要设置椭圆的两个半径。

圆角矩形

  QPainter绘制椭圆的方法如下:

drawRoundedRect(rect:Union[QRectF,QRect], xRadius:float, yRadius:float, mode:Qt.SizeMode=Qt.AbsoluteSize) -> None
drawRoundedRect(x:int, y:int, w:int, h:int, xRadius:float, yRadius:float, mode:Qt.SizeMode=Qt.AbsoluteSize) -> None

  其中参数 mode 是 Qt.SizeMode 的枚举类型,可以取值如下:

Qt.SizeMode.AbsoluteSize     #  椭圆半径是绝对值
Qt.SizeMode.RelativeSize     # 椭圆半径是相对于矩形边长的相对值
import sys

from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtGui import QPainter
from PySide6.QtCore import QRect, Qt

class MyWidget(QWidget):
    def __init__(self):
        # 1、调用父类的__init__()方法
        super().__init__()
        # 2.设置窗口对象大小
        self.resize(700, 500)

    def paintEvent(self, event):
        # 1、创建绘图对象
        painter = QPainter(self)
        # 2、绘制矩形
        painter.drawRect(QRect(10, 10, self.width() - 20, self.height() // 2 - 20))
        # 3、绘制圆角矩形
        painter.drawRoundedRect(QRect(10, self.height() // 2, self.width() - 20, self.height() // 2 - 20), 50, 30, Qt.SizeMode.AbsoluteSize)

if __name__ == "__main__":
    # 1、创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2、创建一个窗口
    window = MyWidget()
    # 3、展示窗口
    window.show()
    # 4、进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

5.5、绘制椭圆

  一个椭圆有两个半径。确定一个椭圆有两种方法:一种是先确定一个矩形边界,在矩形内部作一个与矩形相切的内切椭圆;另一种是先定义一个中心,再定义两个半径。如果矩形边界是正方形或者椭圆的两个半径相等,椭圆就变成了圆。扇形是椭圆的一部分,绘制扇形时除了确定椭圆的几何数据外,还需要确定扇形的起始角和跨度角。需要特别注意的是,起始角和跨度角都是用输入值的 1/16 计算。

椭圆和扇形几何示意图

# 绘制椭圆
drawEllipse(center:[QPoint, QPointF], rx:int, ry:int) -> None
drawEllipse(r:QRect) -> None
drawEllipse(r:Union[QRect, QRectF]) -> None
drawEllipse(x:int, y:int, w:int, h:int) -> None
drawEllipse(center:QPainterPath.Element, rx:float, ry:float) -> None

# 绘制扇形
drawPie(rect:Union[QRect, QRectF], a:int, alen:int) -> None
drawPie(x:int, y:int, w:int, h:int, a:int, alen:int) -> None

  绘制弧和绘制弦的参数与绘制扇形的参数相同,只不过是从椭圆上截取的部分不同。QPainter 绘制弧和弦的方法如下:

# 绘制弧
drawArc(rect:Union[Qrect, QRectF], a:int, alen:int) -> None
drawArc(x:int, y:int, w:int, h:int, a:int, alen:int) -> None

# 绘制弦
drawChord(rect:Union[QRect, QRectF], a:int, alen:int) -> None
drawChord(x:int, y:int, w:int, h:int, a:int, alen:int) -> None
import sys

from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtGui import QPainter
from PySide6.QtCore import QRect

class MyWidget(QWidget):
    def __init__(self):
        # 1、调用父类的__init__()方法
        super().__init__()
        # 2、设置窗口对象大小
        self.resize(700, 500)

    def paintEvent(self, event):
        # 1、创建绘图对象
        painter = QPainter(self)
        # 2、绘制椭圆
        painter.drawEllipse(QRect(10, 10, self.width() // 2 - 20, self.height() // 2 - 20))
        # 3.绘制扇形
        painter.drawPie(QRect(self.width() // 2, self.height() // 2, self.width() // 2 - 20, self.height() // 2 - 20), 45 * 16, 60* 16)

if __name__ == "__main__":
    # 1、创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2、创建一个窗口
    window = MyWidget()
    # 3、展示窗口
    window.show()
    # 4、进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

5.6、绘制多边形

  QPainter 绘制多边形和凸多边形的方法如下所示。

# 绘制多边形
drawPolygon(arg__1:Sequence[QPoint], arg__2:Qt.FillRule) -> None
drawPolygon(arg__1:Sequence[QPointF], arg__2:Qt.FillRule) -> None
drawPolygon(polygon:Union[QPolygon, Sequence[QPoint], QRect], fillRule:Qt.FillRule=Qt.OddEvenFill) -> None
drawPolygon(polygon:Union[QPolygonF, Sequence[QPointF], QPolygon, QRectF], fillRule:Qt.FillRule=Qt.OddEvenFill) -> None

# 绘制凸多边形
drawConvexPolygon(polygon:Union[QPolygon, Sequence[QPoint], QRect]) -> None
drawConvexPolygon(polygon:Union[QPolygonF, Sequence[QPointF], QPolygon, QRectF]) -> None

  使用这些方法时,需要给出多边形或凸多边形的顶点,系统会自动在起始点和终止点之间建立直线,使多边形封闭。参数 fillRule 是 Qt.FillRule 的枚举类型,用于确定一个点是否在图形内部,在内部的区域可以进行填充。fillRule 可以取值如下:

Qt.FillRule.OddEvenFill
Qt.FillRule.WindingFill

  Qt.FillRule.OddEvenFill 是奇偶填充规则,要判断一个点是否在图形中,可以从该点向图形外引一条水平线,如果该水平线与图形的交点个数为奇数,那么该点在图形中。Qt.FillRule.WindingFill 是非零绕组填充规则,要判断一个点是否在图形中,可以从该点向图形外引一条水平线,如果该水平线与图形的边线相交,这个边线是顺时针绘制的,就记为 1,是逆时针绘制的就记为 -1,然后将所有数值相加,若结果不为 0,那么该点就在图形中。

填充规则

import sys

from math import sin, cos, pi
from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtGui import QPainter, QPen, QBrush
from PySide6.QtCore import QRect, Qt, QPointF

class MyWidget(QWidget):
    def __init__(self):
        # 1、调用父类的__init__()方法
        super().__init__()
        # 2、设置窗口对象大小
        self.resize(700, 500)

    def paintEvent(self, event):
        # 1、创建绘图对象
        painter = QPainter(self)

        # 2、设置钢笔
        pen = QPen()
        pen.setWidth(2)
        painter.setPen(pen)

        # 3、设置画刷
        brush = QBrush(Qt.BrushStyle.SolidPattern)
        painter.setBrush(brush)

        r = 100
        x = self.width() / 4
        y = self.height() / 4

        p1 = QPointF(r * cos(-90 * pi / 180) + x, r * sin(-90 * pi / 180) +y)
        p2 = QPointF(r * cos(-18 * pi / 180) + x, r * sin(-18 * pi / 180) +y)
        p3 = QPointF(r * cos(54 * pi / 180) + x, r * sin(54 * pi / 180) +y)
        p4 = QPointF(r * cos(126 * pi / 180) + x, r * sin(126 * pi / 180) +y)
        p5 = QPointF(r * cos(198 * pi / 180) + x, r * sin(198 * pi / 180) +y)

        # 4、绘制多边形
        painter.drawPolygon([p1, p2, p3, p4, p5], Qt.FillRule.OddEvenFill)
        offset = QPointF(self.width() / 2, 0)
        painter.drawConvexPolygon([p1 + offset, p2 + offset, p3 + offset, p4 + offset, p5 + offset])

if __name__ == "__main__":
    # 1、创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2、创建一个窗口
    window = MyWidget()
    # 3、展示窗口
    window.show()
    # 4、进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

六、绘制文本

  可以在指定位置绘制文本,绘制文本时,通常需要先用 setFont(QFont) 方法设置 QPainter 的字体。绘制文本的方法如下所示,所绘文本默认是反锯齿的。

drawStaticText(topLeftPosition:Union[QPoint, QPointF, QPainterPath.Element], staticText:QStaticText) -> None
drawStaticText(left:int, top:int, staticText:QStaticText) -> None

drawText(p:Union[QPoint, QPointF, QPainterPath.Element], s:str) -> None
drawText(p:QPoint, s:str) -> None
drawText(r:Union[QRect, QRectF], flags:int, text:str) -> None
drawText(x:int, y:int, s:str) -> None
drawText(x:int, y:int, w:int, h:int, flags:int, text:str) -> None

  绘制文本可以用 drawStaticText() 方法,该方法比较快,且每次不用重新计算文本的排列位置。QStaticText 是静态文本类,用 QStaticText 类创建静态文本的方法是 QStaticText()QStaticText(str)。可以用 QStatciText 的 setText(str) 方法设置文本;用 setTextFormat(Qt.TextFormat) 方法设置静态文本的格式,参数 Qt.TextFormat 可取值如下:

Qt.TextFormat.PlainText
Qt.TextFormat.RichText
Qt.TextFormat.AutoText
Qt.TextFormat.MarkdownText
import sys

from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtGui import QPainter

class MyWidget(QWidget):
    def __init__(self):
        # 1、调用父类的__init__()方法
        super().__init__()
        # 2、设置窗口对象大小
        self.resize(700, 500)

    def paintEvent(self, event):
        # 1、创建绘图对象
        painter = QPainter(self)
        # 2.绘制文本
        painter.drawText(10, 100, "你好,世界!")

if __name__ == "__main__":
    # 1、创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2、创建一个窗口
    window = MyWidget()
    # 3、展示窗口
    window.show()
    # 4、进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

七、绘图路径

  为了将简单的图形组合成复杂且封闭的图形,需要用到绘图路径 QPainterPath,前面介绍的绘图方法所绘制的图形都可以加入 QPainterPath 中,构成 QPainterPath 的元素。用 QPainter 的 drawPath(path:QPainterPath) 方法或 strokePath(path:QPainterPath,pen:Union[QPen,Qt.PenStyle,QColor]) 方法可以将绘图路径的图形绘制出来,用绘图路径绘制的图形不论是否封闭,都隐含是封闭的,可以在其内部进行填充。

  QPainterPath 是一些绘图命令按照先后顺序的有序组合,创建一次后可以反复使用。

  用 QPainterPath 类创建绘图路径实例对象的方法如下所示:

QPainterPath()
QPainterPath(other:QPainterPath)
QPainterPath(startPoint:Union[QPoint, QPointF, QPainterPath.Element])

  其中 startPoint 是绘制路径的起始点,也可以用绘图路径的 moveTo(Union[QPointF,QPoint])moveTo(x:float,y:float) 方法将绘图路径的当前点移到起始点。

  QPainterPath 类绘图常用的方法如下:

currentPosition() -> QPointF                                            # 获取当前的起始点QPointF

# 将当前点移动到指定的点,作为下一个绘图单元的起始点
moveTo(p:Union[QPoint, QPointF]) -> None
moveTo(x:float, y:float) -> None

# 将当前点移动到指定矩形框内的椭圆上,angle是起始角度
arcMoveTo(rect:Union[QRect, QRectF], angle:float) -> None
arcMoveTo(x:float, y:float, w:float, h:float, angle:float) -> None

# 在当前点与指定点之间绘制直线
lineTo(p:Union[QPoint, QPointF, QPointerPath.Element]) -> None
lineTo(x:float, y:float) -> None

# 在当前点和终点间绘制三次贝塞尔曲线,前两个点是中间控制点,最后一个点是终点
cubicTo(ctrlPt1:Union[QPoint, QPointF, QPainterPath.Element], ctrlPt2:Union[QPoint, QPointF, QPainterPath.Element], endPty:Union[QPoint, QPointF, QPainterPath.Element]) -> None
cubicTo(ctrlPt1x:float, ctrlPt1y:float, ctrlPt2x:float, ctrlPt2y:float, endPtx:float, endPty:float) -> None

# 在当前点和终点间添加二次贝塞尔曲线,第一个点是控制点
quadTo(ctrlPt:Union[QPoint, QPointF, QPointerPath.Element], endPt:Union[QPoint, QPointF, QPointerPath.Element]) -> None
quadTo(ctrlPtx:float, ctrlPty:float, endPtx:float, endPty:float) -> None

# 在矩形框内绘制圆弧,startAngle和arcLength分别是起始点和跨度角
arcTo(rect:Union[QRect, QRectF], startAngle:float, arcLength:float) -> None
arcTo(x:float, y:float, w:float, h:float, startAngle:float, arcLength:float) -> None

# 绘制封闭的椭圆
addEllipse(rect:Union[QRect, QRectF]) -> None
addEllipse(center:Union[QPoint, QPointF], rx:float, ry:float) -> None
addEllipse(x:float, y:float, w:float, h:float) -> None

# 绘制矩形
addRect(rect:Union[QRect, QRectF]) -> None
addRect(x:float, y:float, w:float, h:float) -> None

# 绘制圆角矩形
addRoundedRect(rect:Union[QRect, QRectF], xRadius:float, yRadius:float, mode:Qt.SizeMode=Qt.AbsoluteSize) -> None
addRoundedRect(x:float, y:float, w:float, h:float, xRadius:float, yRadius:float, mode:Qt.SizeMode=Qt.AbsoluteSize) -> None

# 绘制多边形
addPolygon(polygon:Union[QPolygon, QPolygonF, QPointF, Sequence[QPointF]]) -> None

# 绘制文本
addText(point:Union[QPoint, QPointF, QPainterPath.Element], f:Union[QFont, str, Sequence[str]], text:str) -> None
addText(x:float, y:float, f:Union[QFont, str, Sequence[str]], text:str) -> None

addRegion(region:Union[QRegion, QBitmap, QPolygon, QRect]) -> None      # 绘制QRegion的范围
addPath(path:QPainterPath) -> None                                      # 将其它绘图路径添加进来
# 将绘图路径进行平移
translate(offset:Union[QPoint, QPointF, QPainterPath.Element]) -> None
translate(dx:float, dy:float)

closeSubpath() -> None                                                  # 有当前子路径的首尾绘制直线,开始新的子路径的绘制
connectPath(path:QPainterPath) -> None                                  # 由当前路径的终点位置与给定路径的起始位置绘制直线

  路径是由多个图形构成的,每个图形中可能包括直线、贝塞尔曲线、弧、椭圆、多边形、矩形或文本。使用 moveTo() 方法把当前路径移到指定位置,作为绘图开始的起点位置,移动当前点会启用一个新的子路径,并自动封闭之前的路径。

  QPainterPath 类查询常用的方法如下:

angleAtPercent(t:float) -> float                                        # 获取绘图路径长度百分比处的切向角
slopeAtPercent(t:float) -> float                                        # 获取斜率 
boundingRect() -> QRectF                                                # 获取路径所在的边界矩形区域
capacity() -> int                                                       # 获取路径中单元的数量
elementCount() -> int                                                   # 获取绘图路径的单元数量
clear() -> None                                                         # 清空绘图路径中的元素

contains(p:Union[QPoint, QPointF]) -> bool                              # 如果指定的点在路径内部,则返回True
contains(rect:QRect) -> bool                                            # 如果路径包含指定的矩形,则返回True
contains(pt:QPainterPath.Element) -> bool                               # 如果包含指定的路径,则返回True

controlPointRect() -> QRectF                                            # 获取包含路径中所有点和控制点构成的矩形

intersected(r:QPainterPath) -> QPainterPath                             # 获取绘图路径和指定路径填充区域相交的路径
united(r:QPainterPath) -> QPainterPath                                  # 获取绘图路径与指定路径填充区域合并的路径
subtracted(r:QPainterPath) -> QPainterPath                              # 获取减去指定路径后的路径

intersects(p:QPainterPath) -> bool                                      # 获取绘图路径与指定路径是否相交
intersects(rect:QRectF) -> bool                                         # 获取绘图路径与矩形区域是否相交
isEmpty() -> bool                                                       # 获取绘图路径是否为空
length() -> float                                                       # 获取绘图路径的长度
pointAtPercent(t:float) -> QPointF                                      # 获取指定长度百分比处的点

reserve(size:int) -> None                                               # 在内存中预留指定数量的绘图单元内存空间

setElementPositionAt(i:int, x:float, y:float) -> None                   # 将索引是i的元素的x和y坐标设置成指定值
setFillRule(fillRule:Qt.FillRule) -> None                               # 设置填充规则

simplified() -> QPainterPath                                            # 获取简化后的路径,如果路径元素有交叉或重合,则简化后的路径没有重合

swap(other:QPainterPath) -> None                                        # 交换绘图路径

toReversed() -> QPainterPath                                            # 获取反转后的路径
toSubpathPolygons(matrix:QTransform=QTransform()) -> List[QPolygonF]    # 将每个元素转换成QPolygonF

translated(offset:Union[QPoint, QPointF]) -> QPainterPath               # 获取平移后的绘图路径
translated(dx:float, dy:float) -> QPainterPath                          # 获取平移后的绘图路径
import sys

from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtGui import QPainterPath, QPainter, QPen, QBrush, Qt
from PySide6.QtCore import QPointF

class MyWidget(QWidget):
    def __init__(self):
        # 1、调用父类的__init__()方法
        super().__init__()
        # 2、设置窗口对象大小
        self.resize(700, 500)

    def paintEvent(self, event):
        # 1、创建路径
        path = QPainterPath()

        center = QPointF(self.width() / 2, self.height() / 2)
        r = min(self.width() , self.height()) / 3

        # 2、将当前点移动到指定点,作为起始点
        path.moveTo(center)

        # 3、绘制圆弧
        path.arcTo(center.x() - r, center.y() - r, 2 * r, 2 * r, 0, 360)

        # 4、设置填充方式
        path.setFillRule(Qt.FillRule.WindingFill)

        # 5、创建绘画对象
        painter = QPainter(self)

        # 6、创建钢笔对象
        pen = QPen()
        pen.setWidth(5)
        pen.setColor(Qt.GlobalColor.black)

        # 7、使用钢笔对象
        painter.setPen(pen)

        # 8、创建画刷对象
        brush = QBrush(Qt.BrushStyle.SolidPattern)

        # 9、使用画刷对象
        painter.setBrush(brush)

        # 10、绘制路径
        painter.drawPath(path)

        super().paintEvent(event)

if __name__ == "__main__":
    # 1、创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2、创建一个窗口
    window = MyWidget()
    # 3、展示窗口
    window.show()
    # 4、进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

八、填充

  用 QPainter 绘图时,如果所绘制的图形是封闭的,且为 QPainter 设置了画刷,则系统自动在封闭的图形内填充画刷的图案,封闭的图形包括绘图路径、矩形、椭圆、多边形。除此之外,还可以为指定的矩形范围填充图案,此时不需要有封闭的边界线。

  QPainter 类的用来填充的常用方法如下:

# 为指定的路径填充颜色
fillPath(path:QPainterPath, brush:Union[QBrush, Qt.BrushStyle, Qt.GlobalColor, QColor, QGradient, QImage, QPixmap]) -> None

# 用画刷填充指定的矩形区域
fillPath(path:Union[QRect, QRectF], brush:Union[QBrush, Qt.BrushStyle, Qt.GlobalColor, QColor, str, QGradient, QImage, QPixmap]) -> None
# 用颜色和渐变色填充指定的矩形区域
fillRect(x:int, y:int, w:int, h:int, color:Union[QBrush, Qt.BrushStyle, Qt.GlobalColor, QColor, str, QGradient, QImage, QPixmap]) -> None

# 擦除指定区域的填充
eraseRect(rect:Union[QRect, QRectF]) -> None
eraseRect(x:int, y:int, w:int, h:int) -> None

setBackground(bg:Union[QBrush, QColor, Qt.GlobalColor, QGradient]) -> None              # 设置背景色
background() -> QBrush                                                                  # 获取背景画刷
setBackgroundMode(mode:Qt.BGMode) -> None                                               # 设置背景模式
setBrushOrigin(arg__1:Union[QPoint, QPointF, QPainterPath.Element]) -> None             # 设置画刷的起始点
setBrushOrigin(x:int, y:int) -> None                                                    # 设置画刷的起始点
brushOrigin() -> None                                                                   # 获取起始点QPoint

  用 fillRect() 方法可以给指定的矩形区域绘制填充颜色,这时无须封闭的空间,也不会绘制出轮廓;用 eraseRect() 方法可以擦除矩形区域的填充。

  用 setBackgroundMode(Qt.BGMode) 方法设置背景的模式,其中参数 Qt.BGMode 可以取值如下:

Qt.BGMode.TransparentMode    # 透明模式
Qt.BGMode.OpaqueMode         # 不透明模式

  用 setBackground(Union[QBrush,QColor,Qt.GlobalColor,QGradient]) 方法设置背景色,背景色只有在不透明模式下才起作用。

  用 setBrushOrigin(Union[QPointF,QPoint])setBrushOrigin(int,int)setBrushOrigin(QPoint) 方法设置画刷的起始点,起始点会影响纹理、渐变色的布局。

import sys

from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtGui import QPainter
from PySide6.QtGui import QLinearGradient, QPen, QBrush
from PySide6.QtCore import QPointF, Qt

class MyWidget(QWidget):
    def __init__(self):
        # 1、调用父类的__init__()方法
        super().__init__()
        # 2、设置窗口对象大小
        self.resize(700, 500)

    def paintEvent(self, event):
        # 1、创建绘图对象
        painter = QPainter(self)

        # 2.1、使用线性渐变充当文字颜色
        linear_1 = QLinearGradient(QPointF(0, 0), QPointF(self.width(), self.height()))
        # 2.2、设置颜色
        linear_1.setStops([(0, Qt.GlobalColor.red), (0.3, Qt.GlobalColor.yellow), (0.6, Qt.GlobalColor.green), (1, Qt.GlobalColor.blue)])
        # 2.3、设置扩展模式
        linear_1.setSpread(QLinearGradient.Spread.ReflectSpread)
        # 2.4、用线性渐变定义画刷
        brush_1 = QBrush(linear_1)

        # 3、创建钢笔对象
        pen = QPen()
        pen.setBrush(brush_1)
        painter.setPen(pen)

        # 4、创建字体对象
        font = painter.font()
        font.setFamily("楷体")
        font.setBold(True)
        font.setPointSize(50)

        # 5、使用字体对象
        painter.setFont(font)

        # 6、设置背景模式不透明
        painter.setBackgroundMode(Qt.BGMode.OpaqueMode)

        # 7.1、使用线性渐变充当文字颜色
        linear_2 = QLinearGradient(QPointF(0, 0), QPointF(self.width(), self.height()))
        # 7.2、设置颜色
        linear_2.setStops([(0, Qt.GlobalColor.blue), (0.3, Qt.GlobalColor.green), (0.6, Qt.GlobalColor.red), (1, Qt.GlobalColor.white)])
        # 7.3、设置扩展模式
        linear_2.setSpread(QLinearGradient.Spread.ReflectSpread)
        # 7.4、用线性渐变定义画刷
        brush_2 = QBrush(linear_2)

        # 8、设置背景画刷
        painter.setBackground(brush_2)

        # 9、设置画刷的起始点
        painter.setBrushOrigin(0, 0)

        # 10、绘制字体
        painter.drawText(100, 100, "你好,世界!")

if __name__ == "__main__":
    # 1、创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2、创建一个窗口
    window = MyWidget()
    # 3、展示窗口
    window.show()
    # 4、进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

九、绘制图像

  QPainter 还可以把 QPixmap、QImage 和 QPicture 图像直接绘制在绘图设备上。

  绘制 QPixmap 图像的方法如下所示,可以将图像按照原始尺寸显示,也可以缩放图像到一个矩形区域中显示,还可以从原图像上截取一部分绘制到一个矩形区域。

# 指定绘图设备上的一个点作为左上角,按照图像原始尺寸显示
drawPixmap(p:Union[QPoint, QPointF, QPainterPath.Element], pm:Union[QPixmap, QImage, str]) -> None
drawPixmap(x:int, y:int, pm:Union[QPixmap, QImage, str]) -> None

# 指定绘图设备上的矩形区域,以缩放尺寸方式显示
drawPixmap(r:QRect, pm:Union[QPixmap, QImage, str]) -> None
drawPixmap(x:int, y:int, w:int, h:int, pm:Union[QPixmap, QImage, str]) -> None

# 指定绘图设备上的一个点和图像的矩形区域,裁剪显示图像
drawPixmap(p:Union[QPoint, QPointF, QPainterPath.Element], pm:Union[QPixmap, QImage, str], sr:Union[QRect, QRectF]) -> None
drawPixmap(x:int, y:int, pm:Union[QPixmap, QImage, str], sx:int, sy:int, sw:int, sh:int) -> None

# 指定绘图设备上的矩形区域和图像的矩形区域,裁剪并缩放显示图像
drawPixmap(targetRect:Union[QRect, QRectF], pixmap:Union[QPixmap, QImage, str], sourceRect:Union[QRect, QRectF]) -> None
drawPixmap(x:int, y:int, w:int, h:int, pm:Union[QPixmap, QImage, str], sx:int, sy:int, sw:int, sh:int) -> None

# 以平铺方式绘制图片
drawTiledPixmap(rect:QRect, pm:Union[QPixmap, QImage, str], pos:QPoint=QPoint()) -> None
drawTiledPixmap(rect:Union[QRect, QRectF], pm:Union[QPixmap, QImage, str], offset:Union[QPoint, QPointF, QPainterPath.Element]=QPointF()) -> None
drawTiledPixmap(x:int, y:int, w:int, h:int, pm:Union[QPixmap, QImage, str], sx:int=0, sy:int=0) -> None

# 绘制图像的多个部分,可以对每个部分进行缩放、旋转操作
drawPixmapFragments(fragments:List[QPainter.PixmapFragment], fragmentCount:int, pixmap:Union[QPixmap, QImage, str], hints:QPainter.PixmapFragmentHints=QPainter.PixmapFragmentHints()) -> None

  用 drawPixmapFragments(fragments:List[QPainter.PixmapFragment],fragmentCount:int,pixmap:Union[QPixmap,QImage,str],hints:QPainter.PixmapFragmentHints) 方法可以截取图像的多个区域,并对每个区域进行缩放、旋转操作,其中参数 hints 只能取 QPainter.OpaqueHint;参数 QPainter.PixmapFragment 的创建方法如下:

QPainter.PixmapFragment.create(pos:QPointF,sourceRect:QRectF,scaleX=1,scaleY=1,rotation=0,opacity=1)

  其中 pos 是图像绘制地点,sourceRect 是截取的图像的部分区域,scaleX 和 scaleY 是缩放比例,rotation 是旋转角度,opacity 是不透明度值。

  绘制 QImage 图像的方法如下所示。可以将图像按照原始尺寸显示,也可以缩放图像到一个矩形区域中显示,还可以从原图像上截取一部分绘制到一个矩形区域。

# 在指定位置,按图像实际尺寸显示
drawImage(p:Union[QPoint, QPointF, QPainterPath.ELement], image:Union[QImage, str]) -> None

# 在指定矩形区域内,图像进行缩放显示
drawImage(r:Union[QRect, QRectF], image:Union[QImage, str]) -> None

# 在指定位置,从图像上截取一部分显示
drawImage(p:Union[QPoint, QPointF, QPainterPath.Element], image:Union[QImage, str], sr:Union[QRect, QRectF], flags:Qt.ImageConversionFlags=Qt.AutoColor) -> None
drawImage(x:int, y:int, image:Union[QImage, str], sx:int=0, sy:int=0, sw:int=-1, sh:int=-1, flags:Qt.ImageConversionFlags=Qt.AutoColor) -> None

# 从图像上截取一部分,以缩放形式显示在指定的矩形区域内
drawImage(targetRect:Union[QRect, QRectF], image:Union[QImage, str], sourceRect:Union[QRect, QRectF], flags:Qt.ImageConversionFlags=Qt.AutoColor) -> None

  其中 flags 参数是 Qt.ImageConversionFlags 枚举值,可取值如下:

Qt.ImageConversionFlags.AutoColor
Qt.ImageConversionFlags.ColorOnly
Qt.ImageConversionFlags.MonoOnly

  对于 QPicture 图像,只能在绘图设备的指定点上按照原始尺寸进行绘制。绘制 QPicture 图像的方法如下:

drawPicture(p:Union[QPointF, QPoint, QPainterPath.Element], picture:Union[QPicture,int]) -> None
drawPicture(x:int, y:int, picture:Union[QPicture,int]) -> None
import sys

from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtGui import QPainter, QPixmap

class MyWidget(QWidget):
    def __init__(self):
        # 1、调用父类的__init__()方法
        super().__init__()
        # 2、设置窗口对象大小
        self.resize(700, 500)

    def paintEvent(self, event):
        # 1、创建绘图对象
        painter = QPainter(self)
        # 2、创建图像对象
        pixmap = QPixmap("./1.jpg")
        # 3、绘制图像
        painter.drawPixmap(self.rect(), pixmap)

if __name__ == "__main__":
    # 1、创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2、创建一个窗口
    window = MyWidget()
    # 3、展示窗口
    window.show()
    # 4、进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

十、裁剪区域

  当所绘图形比较大时,若只想显示绘图上的一部分区域的内容,其他区域的内容不显示,就需要使用裁剪区域。用 QPainter 设置裁剪区域的方法下所示:

setClipping(enable:bool) -> None                                                                                # 设置是否启动裁剪区域
hasClipping() -> bool                                                                                           # 获取是否有裁剪区域
setClipPath(path:QPainterPath, op:Qt.ClipOperation=Qt.ReplaceClip) -> None                                      # 用路径设置裁剪区域
setClipRect(rect:Union[QRect, QRectF], op:Qt.ClipOperation=Qt.ReplaceClip) -> None                              # 用矩形框设置裁剪区域
setClipRect(x:int, y:int, w:int, h:int, op:Qt.ClipOperation=Qt.ReplaceClip) -> None                             # 用矩形框设置裁剪区域
setClipRegion(arg_1:Union[QRegion, QBitmap, QPolygon, QRect], op:Qt.ClipOperation=Qt.ReplaceClip) -> None       # 用QRegion设置裁剪区域
clipBoundingRect() -> QRectF                                                                                    # 获取裁剪区域的边界矩形
clipPath() -> QPainterPath                                                                                      # 获取裁剪区域的路径
clipRegion() -> QRegion                                                                                         # 获取裁剪区域

  其中参数 op 是 Qt.ClipOperation 的枚举值,可以取值如下:

Qt.ClipOperation.NoClip
Qt.ClipOperation.ReplaceClip    # 替换裁剪区域
Qt.ClipOperation.IntersectClip  # 与现有裁剪区域取交集

  QRegion 类专门用于定义裁剪区域,QWidget 的 repaint() 方法可以接受 QRegion 参数,限制刷新的范围。用 QRegion 类创建裁剪区域实例的方法如下:

QRegion()
QRegion(bitmap:Union[QBitmap, str])
QRegion(pa:Union[QPolygon, Sequence[QPoint], QRect], fillRule:Qt.FillRule=Qt.OddEvenFill)
QRegion(r:QRect, t:QRegion.RegionType=QRegion.Rectangle)
QRegion(region:Union[QRegion, QBitmap, QPloygon, QRect])
QRegion(x:int, y:int, w:int, h:int, t:QRegion.RegionType=QRegion.Rectangle)

  其中 t 是 QRegion.RegionType 枚举类型,可以取值如下:

QRegion.RegionType.Rectangle
QRegion.RegionType.Ellipse

  QRegion 类的常用方法如下:

boundingRect() -> QRect                                             # 获取边界

contains(p:QPoint) -> bool                                          # 获取是否包含指定的点
contains(r:QRect) -> bool                                           # 获取是否包含矩形

isEmpty()  -> bool                                                  # 获取是否为空
isNull() -> bool                                                    # 获取是否无效

setRects(rect:QRect, num:int) -> None                               # 设置多个矩形区域
rectCount() -> int                                                  # 获取矩形区域的数量

begin() -> QRect                                                    # 获取第一个非重合的矩形
cbegin() -> QRect                                                   # 获取第一个非重合的矩形
end() -> QRect                                                      # 获取最后一个非重合的矩形
cend() -> QRect                                                     # 获取最后一个非重合的矩形

intersects(r:Union[QRegion, QBitmap, QPolygon, QRect]) -> bool      # 获取是否与区域相交  

intersected(r:Union[QRegion, QBitmap, QPolygon, QRect]) -> QRegion  # 获取相交的区域 
subtracted(r:Union[QRegion, QBitmap, QPolygon, QRect]) -> QRegion   # 获取减去区域后的区域
united(r:Union[QRegion, QBitmap, QPolygon, QRect]) -> QRegion       # 获取合并后的区域
xored(r:Union[QRegion, QBitmap, QPolygon, QRect]) -> QRegion        # 获取异或区域

translate(p:QPoint) -> None                                         # 平移区域
translate(dx:int, dy:int) -> None                                   # 平移区域
translated(p:QPoint) -> QRegion                                     # 获取平移后的区域
translated(dx:int, dy:int) -> QRegion                               # 获取平移后的区域

swap(other:Union[QRegion, QBitmap, QPolygon, QRect]) -> None        # 交换区域

  QRegion 可以进行交、减、并和异或运算,这些运算的示意图如下所示。

剪切区域的布尔运算

  用 setRects(Sequence[QRect]) 方法可以设置多个矩形区域,多个矩形之间不能相互交叉,处于同一层的矩形必须有相同的高度,而不能连在一起,多个矩形可以合并成一个矩形。多个矩形首先按 y 值以升序排列,其次按 x 值以升序排列。

import sys

from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtGui import QPainter, QPixmap, QRegion
from PySide6.QtCore import QRect

class MyWidget(QWidget):
    def __init__(self):
        # 1、调用父类的__init__()方法
        super().__init__()
        # 2、设置窗口对象大小
        self.resize(700, 500)

    def paintEvent(self, event):
        # 1、创建绘图对象
        painter = QPainter(self)

        # 2、创建图像对象
        pixmap = QPixmap("./1.jpg")

        # 3、设置是否启动裁剪区域
        painter.setClipping(True)

        # 4、裁剪区域
        rect_1 = QRect(self.width() // 20, self.height() // 10, self.width() // 10 * 4, self.height() // 10 * 3)
        rect_2 = QRect(self.width() // 20, self.height() // 10 * 5, self.width() // 10 * 4, self.height() // 10 * 3)
        rect_3 = QRect(self.width() // 20 * 11, self.height() // 10, self.width() // 10 * 4, self.height() // 10 * 3)
        rect_4 = QRect(self.width() // 20 * 11, self.height() // 10 * 5, self.width() // 10 * 4, self.height() // 10 * 3)

        region_1 = QRegion(rect_1)                                  # 矩形裁剪区域
        region_2 = QRegion(rect_2)                                  # 矩形裁剪区域
        region_3 = QRegion(rect_3, t=QRegion.RegionType.Ellipse)    # 椭圆裁剪区域
        region_4 = QRegion(rect_4, t=QRegion.RegionType.Ellipse)    # 椭圆裁剪区域

        # 5、裁剪区域的布尔运算,并集运算
        region = region_1.united(region_2).united(region_3).united(region_4)

        # 6、用QRegion设置裁剪区域
        painter.setClipRegion(region)

        # 7、绘制图像
        painter.drawPixmap(self.rect(), pixmap)

if __name__ == "__main__":
    # 1、创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2、创建一个窗口
    window = MyWidget()
    # 3、展示窗口
    window.show()
    # 4、进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

十一、图形合成

  图形合成是指当绘制新图形时,绘图设备上已经存在旧图形,对新图形和旧图形进行处理的方法。图形合成是基于像素,将旧图形的颜色值和 Alpha 通道的值与新图形的颜色值和 Alpha 通道的值进行合成处理。图形合成的处理使用 QPainter 的 setCompositionMode(mode:QPainter.CompositionMode) 方法设置,用 compositionMode() 方法获取合成模式,其中参数 mode 是 QPainter.CompositionMode 的枚举值,可以取值如下:

QPainter.CompositionMode.CompositionMode_Source
QPainter.CompositionMode.CompositionMode_SourceIn
QPainter.CompositionMode.CompositionMode_SourceOut
QPainter.CompositionMode.CompositionMode_SourceAtop
QPainter.CompositionMode.CompositionMode_SourceOver         # 默认值

QPainter.CompositionMode.CompositionMode_Destination
QPainter.CompositionMode.CompositionMode_DestinationIn
QPainter.CompositionMode.CompositionMode_DestinationOut
QPainter.CompositionMode.CompositionMode_DestinationAtop
QPainter.CompositionMode.CompositionMode_DestinationOver

QPainter.CompositionMode.CompositionMode_Clear
QPainter.CompositionMode.CompositionMode_Xor
import sys

from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtGui import QPainter, QPixmap
from PySide6.QtCore import QRectF

class MyWidget(QWidget):
    def __init__(self):
        # 1、调用父类的__init__()方法
        super().__init__()
        # 2、设置窗口对象大小
        self.resize(700, 500)

    def paintEvent(self, event):
        # 1、创建绘图对象
        painter = QPainter(self)

        # 2、创建图像对象
        pixmap = QPixmap("./1.jpg")

        # 3、绘制图像
        painter.drawPixmap(self.rect(), pixmap)

        # 4、设置图像的合成方式
        painter.setCompositionMode(QPainter.CompositionMode.CompositionMode_SourceAtop)

        # 5、获取窗口的取行
        rect = QRectF(0, 0, self.width(), self.height())

        # 6.绘制图标
        ico = QPixmap("./1.ico")
        painter.drawPixmap(10, 10, ico)

if __name__ == "__main__":
    # 1、创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2、创建一个窗口
    window = MyWidget()
    # 3、展示窗口
    window.show()
    # 4、进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

标签:__,None,Qt,int,31,float,技术,Union,绘图
From: https://www.cnblogs.com/FlurryHeart/p/18679736

相关文章

  • 学技术学英语:TCP的三次握手和四次挥手
    单词汉语意思音标acknowledge承认,确认/əkˈnɒl.ɪdʒ/acknowledgment确认,承认/əkˈnɒl.ɪdʒ.mənt/duplex双向的/ˈdjuː.pleks/establish建立/ɪˈstæb.lɪʃ/handshake握手,握手协议/ˈhænd.ʃeɪk/re-transmission重传/ˌri......
  • 前端发送Ajax请求的技术Axios
    目录1.引入Axios文件2.使用Axios发送请求2.1请求方法的别名请求的URL地址怎么来的?后端实现前后端交互1.引入Axios文件<scriptsrc="https://unpkg.com/axios/dist/axios.min.js"></script>2.使用Axios发送请求2.1请求方法的别名方法描述axios.get(url[,config......
  • 深入探索 Vue.js 最新组件开发技术:实现动态模块加载器
    随着前端技术的飞速发展,Vue.js的组件化开发理念已经被广泛应用。今天,我们将探索一种最新的技术模式:动态模块加载器在Vue.js中的实现。这种模式可以提升应用的性能,并简化大型项目的组件管理。为什么需要动态模块加载器?在传统的Vue.js开发中,我们经常通过import和requir......
  • 医疗肠胃内窥镜主机技术详解及实现路线(方案)
    医疗肠胃内窥镜主机技术详解及实现路线(基于MCU、FPGA与ARM处理器的实现)摘要肠胃内窥镜主机是现代消化系统疾病诊断与治疗中关键的电子控制与图像处理单元。随着微控制器单元(MCU)、现场可编程门阵列(FPGA)和高性能ARM处理器(如RK3588)的广泛应用,内窥镜主机在图像处理、光源控制和用......
  • CSDN九年码龄追光逐梦:一个00后程序员的技术与成长之路
    在这个科技日新月异的时代,每个程序员都在书写着自己的故事。九年前,我第一次在CSDN上发表技术博客时,还只是一个对编程充满好奇的少年。如今作为一名大二的计算机专业学生,回首这段技术成长之路,有迷茫与困惑,也有突破与欣喜,更有持续不断的热爱与坚持。源于童年的技术启蒙......
  • VMware Avi Load Balancer 31.1.1 发布 - 多云负载均衡平台
    VMwareAviLoadBalancer31.1.1发布-多云负载均衡平台应用交付:多云负载均衡、Web应用防火墙和容器Ingress服务请访问原文链接:https://sysin.org/blog/vmware-avi-load-balancer-31/查看最新版。原创作品,转载请保留出处。作者主页:sysin.org负载均衡平台VMwareAviL......
  • Redis 深度解析:从基础到进阶,全面掌握高效缓存技术
    Redis深度解析:从基础到进阶,全面掌握高效缓存技术引言:Redis作为现代开发中不可或缺的技术之一Redis(RemoteDictionaryServer)作为一种开源的高性能键值数据库,在实际开发中发挥着至关重要的作用。它以其极高的读写性能、丰富的数据结构、持久化机制以及支持多种编程语言的客......
  • 例题_树基础 P5318
    洛谷P5318分析关键词n篇文章m条参考文献引用关系x文章有y参考文献BFS&&DFS结果步骤定义不仅要定义关键词,还要再定义一个容器这里用\(set\)set<int>e[100009];注意要初始化输入输入nmxy这几个关键字计算过程分两步深搜广搜输出先调用函数,在......
  • 202312 青少年软件编程等级考试C/C++ 二级真题答案及解析(电子学会)
    第1题统计指定范围里的数给定一个数的序列S,以及一个区间[L,R],求序列中介于该区间的数的个数,即序列中大于等于L且小于等于R的数的个数。时间限制:1000内存限制:65536输入第一行1个整数n,表示序列的长度。(0<n≤10000) 第二行n个正整数,表示序列里的每一个数,每个数小于等......
  • 大数据毕业设计:python热门音乐数据分析系统+可视化+Flask框架 MySQL数据库 豆瓣音乐
    博主介绍:✌全网粉丝10W+,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业项目实战6年之久,选择我们就是选择放心、选择安心毕业✌>......