Qt示例 | 仿射变换示例 Affine Transformations(八)

96 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第18天,点击查看活动详情

注:示例为Qt 5.1.1中的示例。
本文旨在剖析Qt示例的源码,总结函数使用方法以及编程思想,提高自己的编程能力。

示例运行效果:

1.gif

文件目录:

image.png image.png

具体实现:

ArthurFrame类:

image.png

ArthurFrame类有两个用途,一个是作为XFormView的基类,另一个是在HoverPoints类中为使用QPenGl提供方法。

构造函数:

image.png

构造函数主要实现了数据的初始化。

  • 其中由#ifdef和#endif包涵的部分是对OPenGl想关数据的初始化,包括一个GLWidget指针glw,是否使用OPengl的标记量m_use_opengl,还指定了OpenGL渲染上下文的显示格式:选择支持多样本缓冲区的GL上下文,启用模板缓冲区,启用alpha缓冲区,首选alpha缓冲区大小设置为size。

设置应用程序的新的默认QGLFormat为f。例如,设置单缓冲作为默认而不是双缓冲,你的main()可能包含这样的代码:

QApplication a(argc, argv);
QGLFormat f;
f.setDoubleBuffer(false);
QGLFormat::setDefaultFormat(f);
  • 还对除了关于OPenGl的相关变量做了初始化,包括一个文本类m_document,是否显示文本的标记量m_show_doc,一个标题的背景图m_tile,并初始化了背景框的颜色。

image.png

图中灰色圈起来的地方就是(0,0,64,64,color)和(64,64,64,64,color)。

enableOpenGL函数:

image.png

打开OpenGl参数传true,关闭OpenGl参数传false。

  • 首先做了一个避免重复操作的判断,如果传入的参数与当前的状态相同,则直接返回不做处理。
  • 接下来,创建GLWidget,设置它的背景自动填充,关闭自动交换缓存开关。并发出一个更新大小的事件。
  • 然后保存传入的状态值。
  • 最后,如果参数为true,则显示我们创建的OPenGl渲染窗口。如果为false,则隐藏此窗口。并调用update()更新。

QApplication::postEvent: 将事件事件添加到事件队列中,对象接收者作为事件的接收者,并立即返回。第一个参数为事件的接收者,第二个参数为要发送的事件,他还有一个默认参数,为事件的优先级,默认为Qt::NormalEventPriority。

paintEvent函数:

image.png

这里指定了绘图设备从哪里开始绘制。当设置了自定义图片时并且不使用opengl时创建一个QImage对象,在QImage上绘制四个矩形。否则如果是opengl,则在opengl的widget上绘制矩形,不是opengl,则直接在窗体上开始绘制。

  • QImage类提供了一个独立于硬件的图像表示,它允许直接访问像素数据,并且可以用作绘制设备。

  • Qt提供了四个处理图像数据的类:QImage, QPixmap, QBitmap和QPicture。QImage是为I/O和直接像素访问和操作而设计和优化的,而QPixmap是为在屏幕上显示图像而设计和优化的。QBitmap只是一个继承QPixmap的方便类,确保深度为1。最后,QPicture类是一个记录和回放QPainter命令的绘制设备。

image.png

这里使用裁减路径的方式画出圆角矩形边框。

image.png

当需要绘制文本文件(what's this的描述显示)时,调用paintDescription()函数完成文本文件的绘制。m_prefer_image这里么有进行设置,所以一直是false,不会调用里面的功能。最后判断是否使用opengl,如果使用opengl并且此类继承了引号中的几个类中的一个,或者显示文本文件,都将调用缓冲区交换函数。

用屏幕外缓冲区交换屏幕内容。这只在小部件的格式指定了双缓冲区模式时有效。

未完待续...