文章目录
- 前言
- 一、Qt图形系统介绍
- 二、Graphics/View框架
前言
Qt的Graphics/View框架被用来存放、显示二维图形元素,处理那些对图形元素进行操作的交互命令。
一、Qt图形系统介绍
Qt 应用程序的图形界面包含各种控件,比如窗口、按钮、滚动条等。所有这些控件对象都具有一个共同的基类QWidget。一个QWidget对象是构成图形界面的基本单位。它能够在屏幕上绘制自己,能够处理鼠标、键盘事件。控件所占的屏幕区域总是矩形的。在屏幕上显示多个控件时会按照一定的顺序逐个显示。我们称先被显示的控件位于“底层”,后被显示的位于“顶层”。当多个控件所占区域重叠时,顶层控件会遮挡底层控件。
我们知道,控件之间可以形成父子关系,比如对于一个对话框,其中的按钮、滚动条等为子控件,对话框为父控件。子控件常常作为父控件的数据成员出现,所以我们也称一个父控件包含一个子控件,或者一个子控件被嵌入到一个父控件中。大部分控件都作为子控件出现,没有父控件的控件被称为窗口。通常,一个窗口的四周具有边框,其顶部具有一个标题。Qt的QMainWindow以及QDialog是常用的窗口控件。父控件的尺寸较大,子控件的尺寸较小。当子控件的部分或者全部落在父控件区域之外时,只有位于父控件区域之内的部分才会被绘制。一个图形界面由多个控件层叠而成,父控件位于底层,而子控件位于顶层。Qt总会先绘制底层的控件再绘制顶层的控件,以形成层叠效果。
绘制一个几何图形需要做两方面工作。
(1)计算该图形中每个像素的坐标位置。比如在绘制一个线段时,我们往往只是给定起点、终点的坐标,绘制时就需要计算线段上任意一点的坐标。虽然理论上一个线段有无穷多个点,但是由于计算机屏幕、打印机等图形输出设备的分辨率是有限的,我们只需要计算该线段上有限个点的坐标,类QPainter负责完成此项任务。
(2)将计算出来的轨迹输出到特定设备,比如屏幕或者打印机,类QPainterDevice表示这些设备。
程序员通常使用QPainter的构造函数QPainter ( QPaintDevice * device )构造一个对象,调用该对象的图形绘制函数,即可在参数device所指的设备上绘制图形。QPainter提供了丰富的图形绘制函数,经常使用的图形绘制函数如下。drawLine(),drawPolyline()和drawArc()分别绘制直线、折线、曲线,drawRect(),drawEllipse(),drawPolygon(),drawPie()分别绘制矩形、椭圆、多边形、馅饼形。绘制前,我们可以调用setPen()设定线宽、线的颜色等参数。如果被绘制的图形是封闭的,图形内部将被填充。函数setBrush()设置填充颜色、填充模式等。为了输出文字,可以调用drawText(),而setFont()可以设置字体、字号等。
二、Graphics/View框架
Qt的Graphics/View框架被用来存放、显示二维图形元素,处理那些对图形元素进行操作的交互命令。
该框架包含3个核心类:QgraphicsItem,QgraphicsScene,QGraphicsView。QGraphicsItem表示被显示的图形元素。QGraphicsScene表示囊括了所有图形元素的场景。该类只表示一个场景由哪些图形元素组成,并不负责显示其中的元素。QGraphicsView负责显示一个场景中的部分或者全部图形元素。一个场景可以对应多个QGraphicsView对象,以显示一个场景的不同区域,或者以不同的方式来显示该场景。
Graphic/View框架还处理那些对图形元素进行操作的交互命令。例如,当用户单击左键、试图选择某个图形元素时,QGraphicsView将鼠标坐标换算为QGraphicsScene的坐标,遍历各个QGraphicsItem对象,判断哪个图形元素被单击。
QGraphicsScene维护一个列表,记录哪些图形元素被选中。另外,它还维护一个数据结构,记录哪个或者哪些图形元素获得聚焦。用户的键盘事件经由QGraphicsView传递给QGraphicsScene,后者将键盘事件传递给获得聚焦的图形元素。
Graphics View框架涉及如下图所示的3个坐标系。每个图形元素(QGraphicsItem对象)有其自身的坐标系,可以自由选择原点位置,坐标值具有浮点精度。所有图形元素组成的场景(QGraphicsScene对象)拥有自己的坐标系,可以自由选择原点位置,坐标值也具有浮点精度。以上两个坐标系和具体显示设备(比如屏幕)无关,所以它们的坐标值具有浮点精度。每个视图(QGraphicsView对象)也拥有自己的坐标系。由于这个坐标系和具体显示设备密切相关,而任何一个显示设备的分辨率都是有限的,因而这个坐标系中的坐标值只能是整数,不能是浮点数。该坐标系的坐标原点被固定为视图左上角。以上3个类的成员函数仅使用与该类对应的坐标系。
场景中的图形元素在二维空间上可能发生部分或者全部重叠,称为图形元素之间的碰撞。有些应用场合允许碰撞的发生,比如在类似于Visio这样的绘图程序中,用户可以将一个椭圆元素和一个文本元素重叠,得到一个内部有文字标注的椭圆图形。而其他一些应用场合则禁止碰撞的发生。比如在电路板布线程序中,表示电子元件的图形元素不能够碰撞。碰撞的检测是由QGraphicsScene和QGraphicsItem协作完成的。QGraphicsItem有一个虚函数shape(),负责返回其自身的轮廓。QGraphicsScene的成员函数collidingItems()负责查询场景中每个图形元素的轮廓,判断哪些元素和某个指定的元素相撞。