绘图架构Graphics View介绍
在Qt界面库中,对于图形的绘制,在前面一篇文章中(可参考:),介绍了一种使用QPainter实现普通二维图形的绘制方法,该方法在paintEvent事件里编写绘图程序,其本质绘制的图形是位图,这种方法更适合于绘制复杂度不高的固定图形,并且不能实现图项的选择、编辑、拖放、修改等交互功能。
对于需要绘制大量的、需要交互的图形,可使用Graphics View绘图架构,它是一种基于图形项(Graphics Item)的模型/视图模式,这种方式可以在一个场景中可绘制大量图元项,且每个图元项都是可选择、可交互的。
在Graphics View绘图架构中,主要涉及到下面三个类的使用:
1. 场景类(QGraphicsScene):该类提供绘图场景(Scene),场景是不可见的,是一个抽象的管理图形项的容器,可向场景中添加图形项,获取场景中的某个图形项等;
2. 视图类(QGraphicsView):该类提供绘图的视图(View)组件,用于显示场景中的内容。可以为一个场景设置几个视图,用于对同一个数据集提供不同的观察方式;
3. 图形项类(QGraphicsItem):该类提供了一些基本的图形元件,也可在此基础上自定义图形项,它支持各种事件的响应,如鼠标事件、键盘事件、拖放事件等,以实现图形的交互功能。
在Graphics View绘图架构中涉及到了3个坐标系,即场景坐标、视图坐标及图形项坐标。其中,场景坐标类似于QPainter的逻辑坐标,一般以场景的中心为原点;视图坐标是窗口界面的物理坐标,其左上角为原点坐标;图形项坐标是局部逻辑坐标,通常以图件的中心为原点。
下面给出一个在Python语言下结合PyQt界面库,使用Graphics View架构进行绘图的例子,例子中也涉及到了坐标系统的理解。
示例说明
该例运行界面如下图所示:
在主窗口的视图上显示了四个图件(图元项),包括三个可选择、可移动且不同填充颜色的圆形,一个标识场景大小的矩形框。当鼠标移动时,在状态栏中实时显示当前鼠标位置的三种坐标,即视图(View)坐标、场景(Scene)坐标及图形项(Item)坐标。
本例主界面的Python程序使用纯代码方式实现,下面给出该例的实现过程。
自定义的视图类设计
由于在视图中需要监视获取当前的鼠标移动位置,故设计了一个单独的基于QGraphicsView基类的视图类,其实现代码如下图所示:
该类中定义了一个自定义信号sigMouseMovePoint,当鼠标移动时,在mouseMoveEvent事件中,将当前的鼠标位置发送出去。
主窗口类设计
主窗口基于QMainWindow类,在其中添加一个视图控件用于显示图件及一个状态栏控件用于显示坐标。其实现代码如下图所示:
其主要代码解释如下:
(1)第25-31行,窗口类的初始化函数,并且设置了视图类sigMouseMovePoint信号响应的槽函数。
(2)第33-48行,在主窗口上创建视图控件并将其设置为中心部件,设置状态栏信息。
(3)第50-67行,在视图中完成图形的绘制。先创建视图的场景,然后创建矩形框,其大小为场景大小,将矩形框添加到场景中,然后依次创建三个圆形,其位置分别为矩形框的左边界、中心及右边界,设置为可移动、可选择及可设置焦点属性,最后将其添加到场景中。
(4)第69-76行,当视图中鼠标移动时,获取三种坐标。其中参数pt为视图坐标。使用视图类的mapToScene函数可将其转换为场景坐标。根据场景坐标可获取当前鼠标位置的图形项,进而由图形项类的mapFromScene函数可得到当前图形项的坐标。得到这些坐标后可在状态栏中进行显示。
完整测试代码
程序完整测试代码如下图所示:
运行后就会出现本文开头所示的软件界面,且在主界面上移动鼠标时,可在状态栏中实时得到三种坐标。
总结
本文例子演示了在Python+PyQt架构下,使用Graphics View绘图架构进行简单绘图的过程,并在例子中给出了三种坐标的转换方法。其绘图过程基本上可总结为下面几个步骤,即创建视图、创建场景、关联场景到视图、在场景中创建各种图形项、完成图形的显示等。
本文由编码那些事原创,请关注+转发+收藏+点赞,带你一起长知识!