5.4.2 案例:图形库 graphics
最后更新于:2022-04-02 00:29:00
### 5.4.2 案例:图形库 graphics
如前所述,Tkinter 是 Python 语言的标准库,可以利用 Tkinter 中的画布构件来绘制图形。 虽然利用 Tkinter 来进行图形编程已经比较简单、方便,但对初学者来说可能还是有点小麻 烦。例如,画布甚至都没有提供画“点”的方法,初学者希望画点时往往不知怎么办。又如, 圆形一般都是通过圆心和半径来定义的,但在画布上画圆形时必须利用界限框(外接正方形) 来定义。另外,对图形的各种操作(如移动图形、修改图形的选项值等)都是通过调用画布 的方法来执行的,而根据面向对象的思想,更容易理解的做法应该是直接针对图形对象发出 操作请求。
由于上述理由,有人①在 Tkinter 之上写了一个更容易使用的图形库——graphics。这个 图形库是为教学目的而开发的,它将 Tkinter 的绘图功能以面向对象的方式重新包装了一下, 使得初学者更容易学习和应用。使用 graphics 提供的功能实际上就是使用 Tkinter 的功能, 但使用者并不知道这一点,也不需要知道这一点,这就是层次体系结构带来的效果。图 5.23 显示了 graphics 与 Tkinter 之间的关系,其中提到的 graphics 定义的各种图形类将在稍后介 绍。
> ① Python Programming: An Introduction to Computer Science 的作者 John Zelle。
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-02-22_56cafce1ed3a6.png)
图 5.23 在 Tkinter 之上开发的 graphics
graphics 模块和说明文档可以从下列网站下载:
[http://mcsp.wartburg.edu/zelle/python](http://mcsp.wartburg.edu/zelle/python)
下载后将 graphics.py 模块与你的图形程序放在一个目录中,或者放在 Python 安装目录 中即可。下面我们简要介绍如何使用 graphics 模块。
首先,需要导入 graphics 模块:
```
>>> from graphics import *
```
其次,创建一个绘图窗口:
```
>>> win = GraphWin("My Graphics Window",300,200)
```
这条语句的含义是在屏幕上创建一个窗口对象,窗口标题为"My Graphics Window",宽 度为 300 像素,高度为 200 像素。三个参数都可以省略,缺省宽度和高度都是 200 像素。窗 口的坐标系仍然是我们熟悉的,即以窗口左上角为原点,x 轴向右,y 轴向下。
通过 Graphwin 类创建绘图窗口的界面实际上是对底层 Tkinter 中创建画布对象界面的重 新包装,也就是说,当程序员利用 graphics 模块创建绘图窗口时,系统会把这个请求向下转 达给 Tkinter 模块,而 Tkinter 模块就创建一个画布对象并返回给上层的 graphics 模块。这样 做不是没事找事多此一举,而是为了改善图形编程界面的易用性、易理解性。
接下去就可以在作图窗口中绘制图形了,稍后将介绍各种图形对象的创建方法。程序结 束后应该关闭图形窗口,为此只需向窗口对象发如下消息即可:
```
>>> win.close()
```
下面介绍 graphics 模块支持的各种图形对象的用法。演示代码中总是假定已经导入了 graphics 模块并创建了绘图窗口 win。
点
graphics 模块提供了类型 Point 用于在窗口中画点。创建点对象的语句模式为:
```
>>> p = Point(,)
```
下面通过一个交互过程来在窗口中创建 Point 对象,并演示 Point 对象的方法的使用。
```
>>> p = Point(100,80)
>>> p.draw(win)
>>> print p.getX(),p.getY() 100 80
>>> p.move(20,30)
>>> print p.getX(),p.getY() 120 110
```
第一条语句创建了一个 Point 对象,该点的坐标为(100,80),变量 p 被赋值为该对象。
这时在窗口中并没有显示这个点,因为还需要让这个点在窗口中画出来,为此只需向对象 p 发送消息 draw(),这就是第二条语句的目的,其意为“请求对象 p 执行 draw(win)方法, 即在窗口 win 中将自己画出来”。第三条语句演示了 Point 对象的另两个方法 getX()和 getY()的使用,分别是获得点的 x 坐标和 y 坐标。第四条语句的含义是请求 Point 对象 p 改变位置,向 x 方向移动 20 像素,向 y 方向移动 30 像素。
此外,Point 对象还提供以下方法:
+ p.setFill():设置点 p 的颜色。
+ p.setOutline:设置轮廓线的颜色。对 Point 来说,与 setFill 没有区别。
+ p.undraw():隐藏对象 p,即在窗口中变成不可见的。注意,隐藏并非删除,对象 p 仍然存在,随时可以重新执行 draw()。
+ p.clone():复制。复制一个与 p 一模一样的对象。
读者一定会觉得通过 Point 类来画点非常容易,但也会奇怪:graphics 是建立在 Tkinter 之上的一层软件,graphics 的所有功能都是依赖于 Tkinter 的功能实现的,但是 Tkinter 中并未提供画点功能啊。对这个疑问的解答很简单:Point 对象其实是 Tkinter 中的一个很小的矩 形(参见图 5.23)!这是通过层次化改善图形编程界面的一个典型例子——当我们要画点时, 就直接创建 Point 对象,而不是像在 Tkinter 中那样很别扭地创建一个矩形。
接下去介绍的其他图形对象就不再像 Point 这样详细解释并演示用法了,希望使用 graphics 模块的读者可以自行练习。
直线
直线类型为 Line,创建直线对象的语句模式为:
```
>>> line = Line(<端点 1>,<端点 2>)
```
其中两个端点都是 Point 对象。
和 Point 一样,Line 对象也支持 draw()、undraw()、move()、setFill()、setOutline()、clone()等方法。此外,Line 对象还支持 setArrow()方法,用于为直线画箭头。
圆形
圆形类型为 Circle,创建圆形对象的语句模式为:
```
>>> c = Circle(<圆心>,<半径>)
```
其中圆心是 Point 对象,半径是个数值。
Circle 对象同样支持 draw()、undraw()、move()、setFill()、setOutline()、clone()等方法。此外,Circle 对象还支持 c.getRadius()方法,用于获取圆形对象 c的半径。
椭圆
椭圆类型为 Oval,创建椭圆对象的语句模式为:
```
>>> o = Oval(<左上角>,<右下角>)
```
其中左上角和右下角是两个 Point 对象,用于指定一个矩形,再由这个矩形定义一个内接椭圆。
椭圆对象同样支持 draw()、undraw()、move()、setFill()、setOutline()、 clone()等方法。
矩形
矩形类型为 Rectangle,创建矩形对象的语句模式为:
```
>>> r = Rectangle(<左上角>,<右下角>)
```
其中左上角和右下角是两个 Point 对象,用于指定矩形。
矩形对象同样支持 draw()、undraw()、move()、setFill()、setOutline()、clone() 等方法。此外,矩形还支持的方法包括 r.getP1() 、 r.getP2() 和 r.getCenter(),分别用于获取左上角、右下角和中心,返回值都是 Point 对象。
多边形
多边形类型为 Polygon,创建多边形对象的语句模式为:
```
>>> poly = Polygon(<顶点 1>,..., <顶点 n>)
```
将各顶点用直线相连,即成多边形。
矩形对象同样支持 draw()、undraw()、move()、setFill()、setOutline()、 clone()等方法。此外还支持方法 poly.getPoints(),用于获取多边形的各个顶点。
文本
文本类型为 Text,创建文本对象的语句模式为:
```
>>> t = Text(<中心点>,<字符串>)
```
其中,中心点是个 Point 对象,字符串是显示的文本内容。
文本对象支持 draw()、undraw()、move()、setFill()、setOutline()、clone()等方法,其中 setFill()和 setOutline()方法都是设置文本的颜色。文本对象还支持方法 t.setText(<新字符串>)用于改变文本内容,方法 t.getText()用于获取文本内容,方法 t.setTextColor()用于设置文本颜色。
';