136-QPainter和Graphics/View绘图-QPainter绘图-绘图路径QPainterPath的用法

绘图路径QPainterPath的用法

前文中绘制的几何图形比较简单,各个图形之间也是相互独立的,例如用line()或 lines()方法绘制的多个线条之间相互独立,即便是首尾相连,它们也不是封闭的,不能在其内部填充图案。

为了将简单的图形组合成复杂且封闭的图形,需要用到绘图路径 QPainterPath,前面介绍的绘图方法所绘制的图形都可以加入QPainterPath 中,构成QPainterPath的元素。

用QPainter 的drawPath(path; QPainterPath)方法或strokePath(path:QPainterPath,pen;Union[QPen,Qt.PenStyle,QColor])方法可以将绘图路径的图形绘制出来

用绘图路径绘制的图形不论是否封闭,都隐含是封闭的,可以在其内部进行填充QPainterPath是一些绘图命令按照先后顺序的有序组合创建一次后可以反复使用用QPainterPath类

创建绘图路径实例对象的方法如下所示其中startPoint是绘制路径的起始点,也可以用绘图路径的 moveTo(Union[QPointF,QPoint])或 moveTo(x:float;y:float)方法将绘图路径的当前点移到起始点

from PySide6.QtGui import QPainterPath

QPainterPath(self)-> None
QPainterPath(Other: PySide6.QtGui.QPainterPath)-> None
QPainterPath(startPoint: Union[PySide6.QtCore.QPointF,PySide6.QtCore.QPoint,PySide6.QtGui.QPainterPath.Element])-> None
绘图路径中与绘图有关的方法
QPainterPath的绘图方法及参数类型说 明
moveTo(Union[QPointF,QPoint])将当前点移动到指定的点,作为下一个绘图单元的 起始点
moveTo(x:float,y:float)将当前点移动到指定的点,作为下一个绘图单元的 起始点
currentPosition()获取当前的起始点 QPointF
arcMoveTo(rect: Union[QRectF,QRect],angle: float)将当前点移动到指定矩形框内的椭圆上,最后的 float是起始角度
arcMoveTo(x: float,y: float,w: float,h: float,angle: float)将当前点移动到指定矩形框内的椭圆上,最后的 float是起始角度
lineTo(Union[QPointF,QPoint,QPainterPath.Element])在当前点与指定点之间绘制直线
lineTo(x: float,y: float)在当前点与指定点之间绘制直线
cubicTo(ctrlPt1: Union[QPointF,QPoint,QPainterPath.Element],ctrlPt2: Union[QPointF,QPoint,QPainterPath,Element],endPt: Union[QPointF,QPoint,QPainterPath.Element])在当前点和终点间绘制三次贝塞尔曲线,前两个点 是中间控制点,最后一个点是终点
cubicTo(ctrlPt1x: float,ctrlPtly: float,ctrlPt2x: float,ctrlPt2y:float,endPtx: float,endPty:float)在当前点和终点间绘制三次贝塞尔曲线,前两个点 是中间控制点,最后一个点是终点
quadTo(ctrlPt: Union[QPointF,QPoint,QPainterPath.Element],endPt: Union[QPointF,QPoint,QPainterPath.Element])在当前点和终点间添加二次贝塞尔曲线,第一个点 是控制点
quadTo(ctrlPtx: float,ctrlPty: float,endPtx: float,endPty: float)在当前点和终点间添加二次贝塞尔曲线,第一个点 是控制点
arcTo(rect: Union[QRectF,QRect],startAngle: float,arcLength: float)在矩形框内绘制圆弧,startAngle和 arcLength分别 是起始角和跨度角.
arcTo(x: float,y: float,w: float,h: float,startAngle: float,arcLength: float)在矩形框内绘制圆弧,startAngle和 arcLength分别 是起始角和跨度角.
addEllipse(center: Union[QPointF,QPoint],rx: float,ry: float)绘制封闭的椭圆
addEllipse(rect:Union[QRectF,QRect])绘制封闭的椭圆
addEllipse(x: float,y: float,w: float,h:float)绘制封闭的椭圆
addPolygon(Union[QPolygonF,Sequence[QPointF],QPolygon,QRectF])绘制多边形
addRect(rect: Union[QRectF,QRect])绘制矩形
addRect(x: float,y: float,w; float,h;float)绘制矩形
addRoundedRect(rect: Union[QRectF,QRect],xRadius: float,yRadius; float,mode: Qt.SizeMode=Qt.AbsoluteSize)绘制圆角矩形
addRoundedRect(x: float,y; float,w: float,h: float,xRadius: float,yRadius: float,mode: Qt.SizeMode=Qt.AbsoluteSize)绘制圆角矩形
addText(point: Union[QPointF,QPoint,QPainterPath.Element],f: Union[QFont,str,Sequence[str]],text: str)绘制文本
addText(x:float,y: float,f:Union[QFont,str,Sequence[str]],text:str)绘制文本
addRegion(region: :Union[QRegion,QBitmap,QPolygon,QRect])绘制QRegion的范围
closeSubpath()由当前子路径首尾绘制直线,开始新的子路径的 绘制
connectPath(QPainterPath)由当前路径的终点位置与给定路径的起始位置绘制 直线
addPath(QPainterPath)将其他绘图路径添加进来
translate(dx: float,dy: float)将绘图路径进行平移,dx和dy是x和y方向的移动 量,或用点表示
translate(offset: Union[QPointF,QPoint,QPainterPath.Element])将绘图路径进行平移,dx和dy是x和y方向的移动 量,或用点表示
绘图路径QPainterPath 与查询有关的方法
QPainterPath的查询方法返回值的类型说明
angleAtPercent(t: float)float获取绘图路径长度百分比处的切向角
slopeAtPercent(t: float)float获取斜率
boundingRect()QRectF获取路径所在的边界矩形区域
capacity()int返回路径中单元的数量
clear()None清空绘图路径中的元素
contains(Union[QPointF,QPoint])bool如果指定的点在路径内部,则返回True
contains(QRectF)6001如果矩形区域在路径内部,则返回True
contains(QPainterPath)bool如果包含指定的路径,则返回 True
controlPointRect()QRectF获取包含路径中所有点和控制点构成的矩形
elementCount()int获取绘图路径的单元数量
intersected(QPainterPath)QPainterPath获取绘图路径和指定路径填充区域相交的 路径
united(QPainterPath)QPainterPath获取绘图路径和指定路径填充区域合并的 路径
interseets(QRectF)bo01获取绘图路径与矩形区域是否相交
intersects(QPainterPath)bool获取绘图路径与指定路径是否相交
subtracted(QPainterPath)QPainterPath获取减去指定路径后的路径
isEmpty()bool获取绘图路径是否为空
length()float获取绘图路径的长度
pointAtPercent(float)QPointF获取百分比长度处的点
reserve(size:int)None在内存中预留指定数量的绘图单元内存空间
setElementPositionAt(i; int,x; float,y: float)None将索引是int的元素的x和y坐标设置成指 定值
setFillRule(Qt.FillRule)None设置填充规则
simplified()QPainterPath获取简化后的路径,如果路径元素有交叉或 重合,则简化后的路径没有重合
swap(QPainterPath)None交换绘图路径
toReversed()QPainterPath获取顺序反转后的绘图路径
toSubpathPolygons()List[QPolygonF]将每个元素转换成QPolygonF
toSubpathPolygons(QTransform)List[QPolygonF]将每个元素转换成QPolygonF
translated(dx: float,dy: float)QPainterPath获取平动后的绘图路径,float是x方向和y 方向的移动量,或者用点来表示
translated(Union[QPointF,QPoint])QPainterPath获取平动后的绘图路径,float是x方向和y 方向的移动量,或者用点来表示
方法说明

路径是由多个图形构成的,每个图形中可能包括直线、贝塞尔曲线、弧、椭圆、多边形、矩形或文本。

  • 使用moveTo()方法把当前路径移到指定位置,作为绘图开始的起点位置,移动当前点会启用一个新的子路径,并自动封闭之前的路径
  • 绘制
    • 用lineTo()方法绘制直线,
    • 用arcTo()方法绘制弧,
    • 用quadTo()方法和 cubicTo()方法绘制二次和三次贝塞尔曲线,
    • 用addEllipse()方法绘制封闭的圆,
    • 用addPolygon()方法绘制多边形,
    • 用addRect()方法和addRoundedRect()方法绘制矩形。
    • 在添加直线、弧或贝塞尔曲线后,当前点移动到这些元素的最后位置。
    • 绘制弧时,弧的婴度角与钟表的 3 时方向相同,逆时针方向为正。
  • 路径中每个绘图步骤称为单元(element)
    • 比如 moveTo()lineTo()arcTo)都是单元,addRect()addPolygon()等都是用moveTo()lineTo()、arcTo()等绘制的。
    • 例如 addRect(100,50,200,200)由 movetTo(100,50)、lineTo(300,50)、lineTo(300,250)、lineTo(100,250)和 lineTo(100,50)共5个单元构成
  • 路径可以进行交、并、减和移动操作。
绘图路径OPainterPath的应用实例

作为应用实例,下面我们绘制一个太极图像,程序中使用非零绕组填充

image-20230308144310391

# -*- coding: UTF-8 -*-
# File date: Hi_2023/3/8 14:19
# File_name: 06-绘图路径QPainterPath 的应用实例.py


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


class MyWindow(QWidget):
    def __init__(self,parent=None):
        super().__init__(parent)

        self.resize(600,500)

    def paintEvent(self,event):
        path = QPainterPath()# 路径
        self.center = QPointF(self.width()/ 2,self.height()/ 2)
        r = min(self.width(),self.height())/ 3  # 外面大圆的半径
        r1 = r / 7  # 内部小圆的半径

        path.moveTo(self.center.x(),self.center.y()- r)
        path.arcTo(self.center.x()- r,self.center.y()- r,2 * r,2 * r,90,360)# 外部大圆
        path.arcTo(self.center.x()- r,self.center.y()- r,2 * r,2 * r,90,-180)# 反向半圆

        path.moveTo(self.center.x(),self.center.y()+ r)
        path.arcTo(self.center.x()- r / 2,self.center.y(),r,r,-90,180)# 外部大圆
        path.arcTo(self.center.x()- r / 2,self.center.y()- r / 2 - r / 2,r,r,270,-180)# 反向半圆

        path.moveTo(self.center.x()+ r1,self.center.y()- r / 2)
        path.arcTo(self.center.x()- r1,self.center.y()- r / 2 - r1,2 * r1,2 * r1,0,360)# 内部小圆

        path.moveTo(self.center.x()+ r1,self.center.y()+ r / 2)
        path.arcTo(self.center.x()- r1,self.center.y()+ r / 2 - r1,2 * r1,2 * r1,0,-360)# 内部小圆

        path.setFillRule(Qt.FillRule.WindingFill)# 填充方式

        painter = QPainter(self)
        pen = QPen()
        pen.setWidth(5)
        pen.setColor(Qt.black)
        painter.setPen(pen)

        brush = QBrush(Qt.SolidPattern)
        painter.setBrush(brush)# 设置画刷
        painter.drawPath(path)# 设置绘制路径
        super().paintEvent(event)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = MyWindow()

    win.show()
    sys.exit(app.exec())

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Graphics View 是 Qt 框架中用于绘图的一个模块。下面是一个使用 Graphics View 绘制简单图形的示例程序。 首先,需要在程序中引入 QGraphicsView、QGraphicsScene 和 QGraphicsItem 这三个类的头文件。 然后,在程序的主函数或其他适当的位置,创建一个 QGraphicsView 实例,并设置场景的大小和背景颜色。例如: QGraphicsView *view = new QGraphicsView(); view->setSceneRect(0, 0, 800, 600); view->setBackgroundBrush(Qt::white); 接着,创建一个 QGraphicsScene 实例,并设置场景的大小和背景颜色。例如: QGraphicsScene *scene = new QGraphicsScene(); scene->setSceneRect(0, 0, 800, 600); scene->setBackgroundBrush(Qt::white); 然后,创建一个 QGraphicsItem 的子类,并实现它的绘制函数 paint()。在 paint() 函数中,使用 QPainter 绘制所需的图形,如圆形、矩形等。例如: class MyGraphicsItem : public QGraphicsItem { public: MyGraphicsItem() {} QRectF boundingRect() const override { return QRectF(-50, -50, 100, 100); } void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override { painter->setBrush(Qt::blue); painter->drawEllipse(-50, -50, 100, 100); } }; 最后,将创建的 MyGraphicsItem 添加到场景中,并将场景设置给 QGraphicsView 实例。例如: MyGraphicsItem *item = new MyGraphicsItem(); scene->addItem(item); view->setScene(scene); view->show(); 整个程序的执行过程是,创建一个 QGraphicsView 实例,并设置它的场景为一个 QGraphicsScene 实例。然后,在 QGraphicsScene 中创建一个 QGraphicsItem 的子类,实现绘制函数 paint()。最后,将这个 QGraphicsItem 添加到 QGraphicsScene 中,从而在 QGraphicsView 中显示出来。 这个示例只是 Graphics View 的基础用法,真实的 Graphics View 应用程序会更加复杂,可以通过修改 MyGraphicsItem 的 paint() 函数来实现更多的绘图操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

士别三日,当挖目相待

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值