Qt示例 | 基本图型的绘制(二)

举报
黑兔子 发表于 2022/10/17 16:39:34 2022/10/17
【摘要】 示例运行效果: 文件目录: 具体实现: RenderArea类:RenderArea类继承了QWidget,并使用QPainter渲染当前活动形状的多个副本。首先,定义了一个公共的Shape枚举来保存小部件可以呈现的不同形状(即可以通过QPainter呈现的形状)。然后重新实现构造函数以及QWidget的两个公共函数:minimumSizeHint()和sizeHint()。还重新实现了Q...

示例运行效果:

1.gif

文件目录:

image.png

具体实现:

RenderArea类:

image.png

RenderArea类继承了QWidget,并使用QPainter渲染当前活动形状的多个副本。

首先,定义了一个公共的Shape枚举来保存小部件可以呈现的不同形状(即可以通过QPainter呈现的形状)。
然后重新实现构造函数以及QWidget的两个公共函数:minimumSizeHint()和sizeHint()。
还重新实现了QWidget::paintEvent()函数,以便能够根据指定的参数绘制当前活动的形状。
声明了几个私有的槽函数:setShape()改变RenderArea的形状;setPen()和setBrush()修改小部件的钢笔和画笔,setAntialiased()和setTransformed()修改小部件各自的属性。

构造函数:

image.png

  • 构造函数主要进行初始化小部件的一些变量。
  • 初始化它的形状为Polygon,它的抗锯齿属性设置为false,并将图像加载到小部件的pixmap变量中。最后,设置小部件的背景颜色,从小部件的调色板定义画笔,该画笔将用于呈现背景为白色。

minimumSizeHint函数:

image.png

  • RenderArea继承了QWidget的minimumSizeHint属性,保存了小部件的建议最小大小。如果此属性的值为无效大小,则不建议设置大小。
  • 如果小部件没有布局,QWidget::minimumSizeHint()的默认实现将返回无效的大小,否则将返回布局的最小大小。
  • 函数的重新实现将返回一个宽度为100像素、高度为100像素的QSize。

sizeHint函数:

image.png

  • RenderArea继承了QWidget的sizeHint属性,保存了小部件的推荐大小。如果此属性的值为无效大小,则不建议设置大小。
  • 如果小部件没有布局,QWidget::sizeHint()函数的默认实现将返回无效的大小,否则将返回布局的首选大小。
  • 函数的重新实现将返回一个宽度为400像素、高度为200像素的QSize。

设置形状、画笔、笔刷函数:

image.png

setShape(), setPen()和setBrush()槽函数在每当想要修改RenderArea部件的形状,钢笔或笔刷时进行调用。根据槽参数设置形状,钢笔或画笔,并调用QWidget::update()使改变后的图形在RenderArea小部件中可见。
注: QWidget::update()不会导致立即重绘;而是当Qt返回到主事件循环时,才会进行一个paint事件处理。

RenderArea类:

image.png

设置属性函数:

image.png

使用setAntialiased()和setTransformed()槽函数,可以根据槽函数的参数改变属性的状态,并调用QWidget::update()槽函数,让改变后的属性在RenderArea小部件中可见。

paintEvent函数:

image.png

重新实现QWidget::paintEvent()函数。要做的第一件事是创建图形对象,通过paintEvent函数将绘制各种形状。

  • 首先创建了一个4个qpoint的矢量。使用这个矢量来渲染点、折线和多边形形状。然后创建了一个QRect,在平面中定义一个矩形,使用它作为所有形状的边界矩形,不包括Path和Pixmap。
  • 还创建了一个QPainterPath。QPainterPath类为绘制操作提供了一个容器,使图形形状能够被构造和重用。QPainterPath是由许多图形构建块组成的对象,如矩形、椭圆、直线和曲线。在这个例子中,创建了一个由一条直线和贝塞尔曲线组成的绘制路径。
  • 还定义了一个起始角和一个弧长,将在绘制arc, Chord和Pie形状时使用。

image.png

为RenderArea小部件创建一个QPainter,并根据RenderArea的钢笔和笔刷设置画家的钢笔和笔刷。如果抗锯齿参数选项被选中,设置QPainter的渲染提示。

image.png

  • 渲染RenderArea的形状的多个副本。副本的数量取决于RenderArea小部件的大小,这里使用了两个for循环和小部件的高度和宽度来计算它们的位置。
  • 对于每个副本,首先保存当前的画家状态(将状态压入堆栈)。然后使用QPainter::translate()函数将坐标系统转换到由for循环变量决定的位置。如果省略了坐标系统的转换,所有形状的副本将会在RenderArea小部件的左上角相互叠加呈现。
  • 如果选中了transforms参数选项,那么在使用QPainter::rotate()函数将坐标系顺时针旋转60度并使用QPainter::scale()函数将其缩小之前,要将对坐标系进行额外的转换。最后,将坐标系平移回旋转和缩放之前的位置。
  • 当渲染这个形状时,它看起来就像在三维空间中旋转一样。

image.png

  • 确定RenderArea的形状,并使用相关的QPainter绘图功能渲染它。

image.png

  • 在开始渲染之前,保存了当前的绘制器状态(将状态压入堆栈)。这样做的基本原理是,计算每个形状副本相对于坐标系统中的同一点的位置。当转换坐标系时,除非在开始转换过程前保存当前的绘制状态,否则会失去这一点的知识。
  • 然后,完成渲染形状的副本时,可以使用QPainter::restore()函数,用它的相关坐标系统恢复原始的画家状态。通过这种方式,确保了下一个形状副本将被渲染在正确的位置。
  • 可以使用QPainter::translate()将坐标系统转换回来,而不是保存painter状态。但是,由于除了平移坐标系(当选中Transformation参数选项时)还旋转和缩放坐标系,最简单的解决方案是保存当前的画家状态。

一点感想:

在实现绘图时,一定要充分利用提供的一些现有的方法。

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。